学科分类
目录
JavaScript网页编程

访问对象的构造函数

在原型对象里面有一个constructor属性,该属性指向了构造函数。由于实例对象可以访问原型对象的属性和方法,所以通过实例对象的constructor属性就可以访问实例对象的构造函数。下面通过代码进行演示。

 1  function Person() {}

 2  // 通过原型对象访问构造函数

 3  console.log(Person.prototype.constructor === Person);  // 输出结果:true

 4  // 通过实例对象访问构造函数

 5  var p1 = new Person();

 6  console.log(p1.constructor === Person);       // 输出结果:true

需要注意的是,如果将构造函数的原型对象修改为另一个不同的对象,就无法使用constructor属性访问原来的构造函数了,示例代码如下。

 1  function Person() {}

 2  // 修改原型对象为一个新的对象

 3  Person.prototype = {

 4   sayHello: function() {

 5    console.log('hello');

 6   }

 7  };

 8  var p1 = new Person();

 9  // 使用实例对象p1可以访问新的原型对象中的属性

 10 p1.sayHello();         // 输出结果:hello

 11 // 使用constructor属性无法访问原来的构造函数

 12 console.log(p1.constructor);  // 输出结果:Object() { [native code] }

从上述代码可以看出,p1.constructor的访问结果是Object构造函数,而不是p1原本的构造函数Person。之所以会出现这个效果,是因为第3行为Person.prototype赋值了一个新的字面量对象,这个字面量对象的constructor属性指向的就是Object构造函数,所以p1使用constructor属性访问到的就是Object构造函数了。

为了能在修改了原型对象的情况下仍然能通过constructor属性访问正确的构造函数,我们可以在新的原型对象中将constructor属性指向Person构造函数。示例代码如下。

 1  function Person() {}

 2  Person.prototype = {

 3   constructor: Person, // 手动指向Person构造函数

 4   sayHello: function() {

 5    console.log('hello');

 6   }

 7  };

 8  var p1 = new Person();

 9  console.log(p1.constructor === Person); // 输出结果:true

在上述代码中,由于新的原型对象也是一个对象,这个对象原来的constructor属性指向Object构造函数,所以原来的constructor属性其实是Object.prototype原型对象的属性。第3行将constructor属性指向Person构造函数以后,当通过实例对象访问这个属性时,就直接返回Person构造函数,不再到Object.prototype原型对象中查找了。

在掌握了prototype、proto、constructor这些属性的使用以后,就可以在构造函数、原型对象、实例对象之间互相访问了,下面我们通过图1演示这三者的关系。

img

图1 构造函数、实例对象和原型对象互相访问

点击此处
隐藏目录