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

  那么,我为什么说是自定义构造函数模式呢?这是因为,第一部分中,我们使用的Object构造函数是原生构造函数,显然它是���决不了问题的。只有通过创建自定义的构造函数,从而定义自定义对象类型的属性和方法。代码如下:

1

2

3

4

5

6

7

8

9

10

 

function Person(name,age,school){

    this.name=name;

    this.age=age;

    this.school=school;

    this.sayName=function(){

        console.log(this.name);

    };

}

var person1=new Person("zzw","21","xjtu");

var person2=new Person("ht","18","tjut");

 

  首先我们验证这种自定义的构造模式是否解决了第一个问题。在上述代码之后追加下面的代码:

1

2

 

console.log(person1 <strong>instanceof</strong> Person);//true

console.log(person1 <strong>instanceof</strong> Object);//true

 

  结构都得到了true,对于Object当然没有问题,因为一切对象都是继承自Object的,而对于Person,我们在创建对象的时候用的是Person构造函数,那么得到person1是Person类型的也就没问题了。

  对于第二个问题,答案是显而易见的。很明显,创建大量的对象不会造成代码的重复。于是,自定义构造函数成功解决所有问题。

  A 下面我们对比以下自定义构造函数与工厂模式的不同之处:

  B 对于构造函数,我们还应当注意:

构造函数的函数名需要大写,用以区分与普通函数。

构造函数也是函数,只是它的作用之一是创建对象。

构造函数在创建新对象时,必须使用new操作符。

创建的两个对象person1和person2的constructor(构造函数)属性都指向用于创建它们的Person构造函数。

  C 如何理解构造函数也是函数?

  只要证明构造函数也可以像普通函数一样的调用,那么就可以理解构造函数也是函数了。

1

2

3

4

5

6

7

8

9

10

 

function Person(name,age,school){

    this.name=name;

    this.age=age;

    this.school=school;

    this.sayName=function(){

        console.log(this.name);

    };

}

<strong>Person("zzw","21","xjtu");</strong>

sayName();//zzw

 

  可以看出,我直接使用了Person("zzw","21","xjtu");来像普通函数一样的调用这个构造函数,因为我们把它当作了普通函数,那么函数中的this就不会指向之前所说的对象(这里亦没有对象),而是指向了window。于是,函数一经调用,内部的变量便会放到全局环境中去,同样,对于其中的函数也会在调用之后到全局环境,只是这个内部的函数是函数表达式并未被调用。只有调用即sayName();才能正确输出

  由此,我们证明了构造函数也是函数。

  D 那么这种自定义构造函数就没有任何问题吗?

  构造函数的问题是在每次创建一个实例时,构造函数的方法都需要再实例上创建一遍。由于在JavaScript中,我们认为所有的函数(方法)都是对象,所以每当创建一个实例对象,都会同时在对象的内部创建一个新的对象(这部分内容同样可以在我的博文《JavaScript函数之美~》中找到)。即我们之前创建的自定义构造函数模式相当于下列代码:

1

2

3

4

5

6

 

        function Person(name,age,school){

    this.name=name;

    this.age=age;

    this.school=school;

    this.sayName=new Function("console.log(this.name)");

}

 

?

1

2

 

        var person1=new Person("zzw","21","xjtu");

var person2=new Person("ht","18","tjut");

 

  

  即我们在创建person1和person2的时候,同时创建了两个sayName为对象指针的对象,我们可以通过下面这个语句做出判断:

1

 

console.log(person1.sayName==person2.sayName);//false

 

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

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