深入理解JavaScript中创建对象模式的演变(原型)(7)

  我们可以从上面的例子中看到,Object.keys()方法返回的是其自身的属性。如原型对象只返回原型对象中的属性,对象实例也只返回对象实例自己创建的属性,而不返回继承自原型对象的实例。

E 更简单的原型语法

  在之前的例子中,我们在构造函数的原型对象中添加属性和方法时,每次都要在前面敲一遍Person.prototype,如果属性多了,这样的方法会显得更为繁琐,那么下面我将介绍给大家一种简单的方法。

  我们知道,原型对象说到底它还是个对象,只要是个对象,我们就可以使用对象字面量方法来创建,方法如下:

1

2

3

4

5

6

7

8

9

 

        function Person(){}

Person.prototype={

    name:"zzw",

    age:21,

    school:"xjtu",

    sayName:function (){

        console.log(this.name);

    }

};//原来利用Person.prototype.name="zzw"知识对象中的属性,对于对象并没有任何影响,而这里创建了新的对象<br>          

 

  同样,最开始,我们创建一个空的Person构造函数(大家发现了没有,其实每次我们创建的都是空的构造函数),然后用对象字面量的方法来向原型对象中添加属性。这样既减少了不必要的输入,也从视觉上更好地封装了原型。 但是,这时原型对象的constructor就不会指向Person构造函数而是指向Object构造函数了。

    为什么会这样?我们知道,当我们创建Person构造函数时,就会同时自动创建这个Person构造函数的原型(prototype)对象,这个原型对象也自动获取了一个constructor属性并指向Person构造函数,这个之前的图示中可以清楚地看出来。之前我们使用的较为麻烦的方法(e.g. Person.prototype.name="zzw")只是简单地向原型对象添加属性,并没有其他本质的改变。然而,上述这种封装性较好的方法即使用对象字面量的方法,实际上是使用Object构造函数创建了一个新的原型对象(对象字面量本质即利用Object构造函数创建新对象),注意:此时Person构造函数的原型对象不再是之前的原型对象(而之前的原型对象的constructor属性仍然指向Person构造函数),而和Object构造函数的原型对象一样均为这个新的原型对象。这个原型对象和创建Person构造函数时自动生成的原型对象风马牛不相及。理所应当的是,对象字面量创建的原型对象的constructor属性此时指向了Object构造函数。

      我们可以通过下面几句代码来验证:

1

2

3

4

5

6

7

8

9

10

11

12

 

        function Person(){}

Person.prototype={

    name:"zzw",

    age:21,

    school:"xjtu",

    sayName:function (){

        console.log(this.name);

    }

};

var person1=new Person();

console.log(Person.prototype.constructor==Person);//false

console.log(Person.prototype.constructor==Object);//true

 

  通过最后两行代码我们可以看出Person构造函数的原型对象的constructor属性此时不再指向Person构造函数,而是指向了Object构造函数。但是这并被影响我们正常使用,下面几行代码便可以清楚地看出:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

    function Person(){}

Person.prototype={

    name:"zzw",

    age:21,

    school:"xjtu",

    sayName:function (){

        console.log(this.name);

    }

};

var person1=new Person();

console.log(person1.name);//zzw

console.log(person1.age);//21

console.log(person1.school);//xjtu

person1.sayName();//zzw

 

  下面我将以个人的理解用图示表示(如果有问题,请指出):

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/2053e2e6b354a6d70a92c87859b7c2a9.html