• 对象与原型对象上篇


        13-2对象与原型对象

          13-2-1对象的分类

          在ES6之前,对象可以分为2大类,分别是原生对象和宿主对象。

          ●原生对象

          原生对象又可以分为2类:内置对象和自定义对象。例如前面我们学习过的Date、Math、 正则、数组等,这些就是典型的内置对象。它们是JavaScript这门语 言本身所内置的,我们直接使用即可。

          而自定义对象则是我们开发人员自己定义的对象,例如在JS基础中介绍过的使用{}快速生成对象。这样的对象就可以被称之为自定义对象。

          。宿主对象

          顾名思义,就是依存于某一个特定的环境才会有的对象。一旦离开了特定的环境,则这些对象将不存在。例如前面我们在讲解DOM编程时介绍过

          的widnow、navigator 、history 等对象,这些都是依赖于浏览器环境的。一旦脱离了浏览器环境,这些对象也就不存在了。

          在ES6中,对象的类别得到了扩充,分为了4个类别,分别是普通对象,外来对象,标准对象和内置对象。

          13-2-2原型对象



    迷途 2019/7/23 星期二 19:14:34

    迷途 2019/07/23 19:14:33

          let Computer = function(name,price)f

          this. name = name;this.price = price;

          112CiE Tobject#t U35Rreturn (

          name : xiejie"t

          showSth : functíon()

          console, log("another object");

          console. log(this); 11 FJEDthis1

          Computer, protatype. showSth = function()f

          console. log(this); 11 JEDWthis1311

          let apple = new Computer("S R" , 12000);console. log(apple.name); 11 xiejieapple. showSth();11 another object

          11 [ name: 'xiejie', showSth: [Function: showSthJ ]

    imit E 7ĩ83513. EXíEJLZE. kẞs pQiã gg üïxT e tiRO1EfẞxtE. this QUsft5 bs f5IJ4B


    19:15:01
    迷途 2019/7/23 星期二 19:15:01

    迷途 2019/07/23 19:15:01

          用new运算符调用函数时,该函数总会返回- -个对象,通常情况下,构造函数里面的this就指向返回的这个对象。示例如下:

          Let Computer = function(name, price){

          this.name = name;this,price F price;}

          Computer . prototype. showSth = function(){

          console. log(this); //打印出this所指向的对象console. log('这是一台${this . name}电脑);}

          let apple = new Computer("苹果",12000);console. log( apple. name);//苹果console. log(apple. price);//12000

          apple, showSth();//Computer { name; ' 苹果’,price: 12000 }这是: -台苹果电脑Let asus = new Computer("华硕" , 5000);console. log(asus. name);//华硕console. log (asus. price);//5000

          asus. showSth();//Computer { name; ' 华硕’,price: 5000 }这是一 台华硕电脑

          这里,我们分别实例化出来了两个对象apple和asus。那么,这两个对象就有各自的属性值。



    迷途 2019/7/23 星期二 19:15:11

    13-3-2 ES6类的声明
    ES6中,已经开始越来越贴近其他的高级语言了。在ES6中有了类这个概念,使用class来创建类,然后从类里面实例化对象。
    但是,需要说明的是,虽然有了class这种关键字,但是这只是一种语法糖,背后对象的创建,还

    是使用的是原型的方式。
    具体示例如下:




    迷途 2019/7/23 星期二 19:15:23

    迷途 2019/07/23 19:15:22

    13-3类与对象的创建

    在前面的第一-小节,我们讲述了什么是面向对象,以及什么是类,还有类和对象之间的关系。紧接着在第二小节我们话锋-转,阐述了JavaScript里面不存在类的概念,而是基于一门基于原型的语言。

    既然JavaScript里面不存在类,那么为什么我们还要在第- -小节花大量的篇幅来介绍面向对象里面的类呢?实际上,在JavaScript中 虽然没有类,但是可以通过构造函数来模拟其他编程语言里面的类。从而从构造函数里面实例化对象出来。所以在这- -小节, 我们就来看-下JavaScript中如何书写构造函数来模拟其他语言中的类的。

    13-3-1构造函数

    JavaScript是- -个]很特殊的语言,在ES6之 前都没有类的概念(注: ES6新增了class关键字),而是通过构造函数来模拟其他编程语言里面的类的。构造函数实际上也是函数,不过这种函数是专门用于生产对象的,所以被称之为构造函数。它的外表和普通函数- -模-样,区别只是在于被调用的方式.上面。

    构造函数的函数名有一个不成文的规定,就是首字母要大写,以便和普通函数进行区分。下面的例子就演示了在JavaScript中如何书写一个构造函数:



    迷途 2019/7/23 星期二 19:15:33

    迷途 2019/07/23 19:15:33

    13-3-1构造函数

    JavaScript是一门很特殊的语言,在ES6之前都没有类的概念(注: ES6新增了class关键字),而是通过构造函数来模拟其他编程语言里面的类的。构造函数实际上也是函数,不过这种函数是专]用于生产对象的,所以被称之为构造函数。它的外表和普通函数一模-样,区别只是在于被调用的方式上面。

    构造函数的函数名有一个不成文的规定,就是首字母要大写,以便和普通函数进行区分。下面的例子就演示了在JavaScript中如何书写一个构造函数:

          Let Computer = function(name, price){

          this.name = name;this.price = price;

          Computer. prototype. showSth = function(){

          console. log(这是-台${this. name}电脑);}

    这里,我们创建了一-个Computer类,这个类有两个成员属性,分别是name和price,有一-个成员方法,是showSth()。但是可以看到,这里的成员方法showSth()是书写在Computer类的prototype,上面的。



    迷途 2019/7/23 星期二 19:15:46

    具体示例如下:
    class Computer{
    //构造器
    constructor(name, price){
    this. name = name;this.price = price;

    }
    //原型方法showSth(){
    console.log('这是一台${this .name}电脑^ );

    }
    }
    Let apple = new Computer("苹果" , 12000); console. log(apple.name);//苹果console. log( apple. price);//12000apple. showSth();//这是一台苹果电脑




    迷途 2019/7/23 星期二 19:15:57

    迷途 2019/07/23 19:15:57
    PToto_
    {})
    prototype
    constructor
    [Function Object]
    . proto_
    Dror
    [Function J
    o
    constructor
    原型对象) Dron
    C

    _Proto__
    Otyoefor

    .proto_
    "Clor
    构造函数
    o
    ( [Function Function]
    )
    constructor
    、对象
    COS
    Arravll. Nuncel].Booleant. Singll.Functionll. ablectl自定义购值品报导

    (对象与原型对象关系图)
    通过上面的图我们可以得出以下的结论:
    ●每一个对象都有一个原型对象。我们可以通过_ proto__ 来访问到某个对象的原型对象●通过_ _proto__ 一直向上寻找原型对象的话,最终会找到null
    ●一个构造函数的prototype属性指向-一个对象,而这个对象是通过该构造函数实例化出来
    的对象的原型对象
    ●JavaScript中的根对象是0bject.prototype对象。object . prototype对象是一一个空对
    象。我们在JavaScript中遇到的每个对象,实际上都是从0bject . prototype对象克隆而来的。0bject. prototype对象就是它们的原型。而object. prototype对象的原型为null。




    迷途 2019/7/23 星期二 19:16:08

    13-2-2原型对象
    JavaScript里面,没有类这个概念,只有原型的概念。在JavaScript里 面的每一个对象, 都有一个原型对象,而原型对象上面也有一个自己的原型对象,一层一-层向上找,最终到达null。这听起来感觉有点复杂,这里我们将通过- -张图来进行解释,如下图:




    迷途 2019/7/23 星期二 19:16:20

    迷途 2019/07/23 19:16:19
    这里,我们分别实例化出来了两个对象apple和asus。那么,这两个对象就有各自的属性值。
    但用new调用构造函数时,还要注意一个问题, 如果构造函数显式地返回了一个object类型象,那么此次运算结果最终会返回这个对象,而不是我们之前所期待的this,这里我们通过的两段代码来搞清楚构造函数是否显式返回object类型对象之间的区别,如下:

    正常情况,构造函数没有返回object类型对象,this指向实例化出来对 象
    Let Computer = function (name ,price){
    this. name = name;this.price = price;

    Computer . prototype. showSth = function(){
    console. log(this); //打印出this所指向的对象

    }
    Let apple = new Computer("苹果",12000);console. log(apple.name); //苹果
    apple. showSth(); // Computer { name: ' 苹果’,price: 12000 }

    构造函数显式的返回一个object类型的对象,那么最终使用的就是手动返回的这个对象。
    Let Computer = function (name, price){
    this. name = name;this.price = price;




    迷途 2019/7/23 星期二 19:16:29


          3. constructorl

          i@i5 constructor Æ', F*í]ẞJIê#EJ- ↑Xj ŸẞÆft4. tGiEiš, ñtãiZ↑XfXRXf#жR, 5Jk0F:

          let Computer = function(name,price)[

          this. name = name;this.price = price;]

          Computer, prototype. showSth = function()f

          console. log(' i&Æ- a$íthis . name]@i );]

          let apple = new Computer("#Q" , 12000);

          console. log(apple.const ructor);// [Function: Computer]

          I



    迷途 2019/7/23 星期二 19:16:39

    迷途 2019/07/23 19:16:38

          关键字来提供不同的访问权限。但是在JavaScript中并没有提供对这些关键字的支持。

          不过在JavaScript中要实现封装的方法也非常简单,可以利用函数的作用域来进行模拟。在声明属性的时候,添加关键字(et、const、 var)即可。原因也非常简单,因为构造函数也是函数,既然是函数就会有函数作用域,所以在属性的前面添加了关键字之后使其成为一个局部变量,外部自然而然也就访问不到了。示例如下:

          Let Computer = function name, price){

          this.name = name ;Let price = price;

          Computer. prototype. showSth = function(){

          console. log(这是一台${this. name}电脑~ );}

          Let apple = new Computer("苹果”,12000);

          console. log(apple. name);//苹果

          console. log(apple. price);//undefinedconsole. log(apple._ price);//undefined

          -般来讲,对于私有属性,有一个不成文的规定,那就是习惯使用_开头来命名私有属性。这里我们可以看到,由于我们对price属性进行了封装,所以外部无法访问到。



    迷途 2019/7/23 星期二 19:16:50

    迷途 2019/07/23 19:16:49
    13-3-3静态方法
    所谓静态方法,又被称之为类方法。顾名思义,就是通过类来调用的方法。静态方法的好处在于不需要实例化对象,直接通过类就能够进行方法的调用。

    ES6创建类的方法的时候,可以给方法前面添加一个关键字static,来创建一个静态方法。
    class Computer{
    //构造器
    const ructor(name, price){
    this.name = name;this.price = price;

    }
    //原型方法
    showSth(){ T
    console. log( .这是一台${this . name}电脑);

    //静态方法
    static comStruct(){
    console. log("电脑由显示器,主机,键鼠组成");

    }
    Computer. comStruct(); 
    //电脑由显示器,主机,键鼠组成




    迷途 2019/7/23 星期二 19:16:58


    4. instanceofjklF7

          l

    #JF- -↑XJXE2€- -↑133315J. s↓# iẞtrue, EJtiEfalse

          let Computer = function(name, price)f

          this.name = name;this.price = price;

          Computer. prototype. showSth = function()(

          console. log(' i&- a$[this, name]@Æ" );]

          let apple = new Computer("E R", 12000); .

          console. log(apple instanceof Computer);//trueconsole. log(apple instanceof Array);//false


    19:17:09
    迷途 2019/7/23 星期二 19:17:09

    迷途 2019/07/23 19:17:08

    6. hasOwnProperty(

    #Jí-↑4ÆÆXÆX$*# LñiZMM#xæ L õẞmTЖÉJ. $ẞ#4#a, J!i@true, SOR€ÉmmxTжÉ], J!JjEfalse

          let Computer = function (name, price)[

          this.name = name;this.price = price;

          Computer. prototype . showSth = function()f

          console. log(' iXk B$[this. name]Rü );]

          Computer. prototype.test = "this is a test";let apple = new Computer("E R" , 12000);console. log(apple.test);//this is a test

          console. log( apple. has0wnP roperty("test"));//falseconsole. log( apple: has0wnProperty("name"));//true



    迷途 2019/7/23 星期二 19:17:31

    迷途 2019/07/23 19:17:30

    x- 1. prototype和_ proto_ ^-2. Object.getPrototypeC. 3. constructor属性. 4. instanceof操作符- 5. isPrototypeOf0. 6. hasOwnProperty03 13-5封装
    . 13-5-1 封装基本介绍13-5-2存取器白13-6继承
    13-6-1继承基本介绍
    继承的好处. 继承的缺点白13-6-2对象冒充
    L方法借用模式.13-6-3原型继承. 13-6-4 ES6继承方式白13-7多态(选修)
    -13-7-1 多态简介. 13-7-2实现多态13-7-3多态的意义田13-8 this的指向
    -13-9内置对象添加方法13-10属性特性以及描述符13-11基于对象创建对象a 13-12混入技术
    -13-12-1浅复制与深复制13-12-2用mixin函数添加总结

    13-6-1继承基本介绍
    在程序语言中,面向对象里面的继承是指一个子类去继承-个父类。子类继承了父类之后,父类所有的属性和方法都自动都拥有了。

    继承的好处
    继承最大的好处,就在于代码复用。例如有两个类,这两个类的属性和方法基本相同,那么我们就可以考虑给这两个类写-一个父类

    继承的缺点
    首先如果继承设计得非常复杂,那么整个程序的设计也会变得庞大和臃肿。甚至经常会出现"大猩猩与香蕉"的问题。"大猩猩与香蕉"这个名字来自于Erlang编程语言的创始人Joe Armstrong的文章:你想要一个香蕉,但是得到的是拿着香蕉和整个丛林的大猩猩。

    还有一个问题就是,如果是像C+ +那样的多继承语言,那么还可能会遇到菱形继承的问题。这里我们首先来看一下什么叫做多继承。既然有多继承,自然就有单继承。单继承:所谓单继承,就是指只有一个父类多继承:所谓多继承,就是指有多个父类

    菱形继承问题:首先需要说明,菱形继承问题只会在多继承里面才会出现。例如: A和B都继承MindonBase类,假设Base类 里面有一个成员方法, 那么A和B里面都会有这个成员方法,这个时候A和B
    两个类又都对这个成员方法进行了修改。接下来让一个C来同时继承A和B,那么 这个时候就会产  Q




    迷途 2019/7/23 星期二 19:18:00

    迷途 2019/07/23 19:17:59

          13-4与原型相关的方法

          前面已经介绍了JS里面比较有特色的原型对象,也介绍了在JS里面如何创建构造函数或者类,然后通过构造函数和类来实例化出对象。接下来,我们就来看一下JS中和原型对象相关的一- 些方法。

          1. prototype和_ proto_

          prototype是构造函数上面的一个属性,指向一个对象,这个对象是构造函数实例化出来的对象的原型对象。实例化出来的对象可以通过proto_ 来找到自 己的原型对象。

          Let Computer = function(name, price){

          this.name = name ;this.price = price;}

          Computer. prototype. showSth = function(){

          console. log(这是一台${this . name}电脑);

          Let apple = new Computer("苹果",12000);

          console. log(Computer . prototype);//Computer { showSth: [Function }console. log(apple._ proto__ );//Computer { showSth; [Function] }console. log(Computer. prototype === apple._ proto__ );// true



    迷途 2019/7/23 星期二 19:18:17

    迷途 2019/07/23 19:18:17

    2. Object.getPrototypeOf)

    Bâ7. Lïẞîi_ proto_ жäE!JXJ EXRIX9N, tEFJlXi Object. getPrototypeOfl) жE# - -↑XJ SgR@XJR

          let Computer = function (name,price)f

          this. name = name;this.price = price;

          Computer . prototype. showSth = function()f

          console.log(' i&- B$íthis. name]Aü );3

          let apple = new Computer("4#", 12000);

          console. log(Object. getPrototypeOf (apple));//Computer ( showSth: [Function] 1console. log(apple._ _proto__ );//Computer f showSth: [Function] ]

          console. log(0bject . getPrototypeOf(apple) === apple._ proto__ );//true



    迷途 2019/7/23 星期二 19:18:28

    迷途 2019/07/23 19:18:27
    -般来讲,对于私有属性,有一个不成文的规定,那就是习惯使用_开头来命名私有属性。这里我们可以看到,由于我们对price属性进行了封装,所以外部无法访问到。

    封装后的属性,我们可以将其称之为私有属性。对于外部来讲,私有属性是不可见的,这个我们已经知道了,但是对于内部来讲,私有属性是可见的。这就好比电视机里面的零部件封装后外部无法直接访问到,但是电视机内部是可以使用这个零部件来完成相应的功能的。示例如下:

    Let Computer = function (name,price){
    this. name = name;Let_ price = price;
    this.sayPrice = function(){
    console. log(价格为${_ .price} );

    }
    }
    Computer . prototype. showSth = function(){
    console. log(这是一台${this . name}电脑~ );

    }
    Let apple = new Computer("苹果" , 12000);apple. sayPrice();//价格为12000




    迷途 2019/7/23 星期二 19:18:38

    迷途 2019/07/23 19:18:37

    callf9l]:

          let Person = function(name, age)[

          this. name = name;this.age = age;

          Person. prototype.test = function()[

          console. log("this is a test");

    let Student = function( name, age , gender, score)f  l

          11 XPersoni Fi/this EäF11this6EE#E

          Person. call(this , name , age);this . gender = gender;this.score. = score;

          let xiejie = new Student("i92", 18,"B" ,100);console. log(xiejie.name);// i$%2N3console. log(xiejie.age);//18 Iconsole. log(xiejie.gender);11#console. log(xiejie. score);//100

          xiejie. test();//TypeError: xiejie,test is not a function

  • 相关阅读:
    豆瓣api-简单跨域演示
    MVC4 验证用户登录一个特性搞定
    IIS7.5 不能加载外部引用的第三方JS,CSS,img等一系列静态文件
    三合一网站后台密码重置
    anaconda安装 (开源的Python发行版本)
    通达信指标函数说明大全
    织梦CMS如何修改中英文模板的当前位置
    微信小程序上架需要增值电信业务经营许可证ICP?
    PS抠图玻璃杯227
    PS用通道工具人物头发抠图246
  • 原文地址:https://www.cnblogs.com/jrzqdlgdx/p/11267513.html
Copyright © 2020-2023  润新知