◆

JavaScript constructor 属性与原型详解

2023-02-02 01:370

什么是 constructor

prototype 对象有一个 constructor 属性,默认指向 prototype 对象所在的构造函数。

function P() {}

P.prototype.constructor === P; // true

由于 constructor 属性定义在 prototype 对象上面,意味着可以被所有实例对象继承。

如下代码:p 是构造函数 P 的实例对象,但是 p 自身没有 constructor 属性,该属性其实是读取原型链上面的 P.prototype.constructor 属性。

function P() {}

var p = new P();

p.constructor === P; // true
p.constructor === P.prototype.constructor; // true
p.hasOwnProperty('constructor'); // false

constructor 的作用

  1. 可以得知某个实例对象,到底是哪一个构造函数产生的。

如下代码:constructor 属性确定了实例对象 f 的构造函数是 F,而不是 RegExp。

function F() {}
var f = new F();

f.constructor === F; // true
f.constructor === RegExp; // false
  1. 通过 constructor 属性,就可以从一个实例对象新建另一个实例。

如下代码:x 是构造函数 Constr 的实例,可以从 x.constructor 间接调用构造函数

function Constr() {}

var x = new Constr();

var y = new x.constructor();
y instanceof Constr; // true
  1. 在实例方法中,调用自身的构造函数

下面代码中,createCopy 方法调用构造函数,新建另一个实例。

Constr.prototype.createCopy = function () {
  return new this.constructor();
};

**constructor 属性表示原型对象与构造函数之间的关联关系 **,如果修改了原型对象,一般会同时修改 constructor 属性,防止引用的时候出错。

如下代码:上面代码中,构造函数 Person 的原型对象改掉了,但是没有修改 constructor 属性,导致这个属性不再指向 Person。 由于 Person 的新原型是一个普通对象,而普通对象的 constructor 属性指向 Object 构造函数,导致 Person.prototype.constructor 变成了 Object。

function Person(name) {
  this.name = name;
}

Person.prototype.constructor === Person; // true

Person.prototype = {
  method: function () {},
};

Person.prototype.constructor === Person; // false
Person.prototype.constructor === Object; // true

正确的写法

  • 要么将 constructor 属性重新指向原来的构造函数
  • 要么只在原型对象上添加方法
// 坏的写法
C.prototype = {
  method1: function (...) { ... },
  // ...
};

// 好的写法
C.prototype = {
  constructor: C,
  method1: function (...) { ... },
  // ...
};

// 更好的写法
C.prototype.method1 = function (...) { ... };

constructor.name

如果不能确定 constructor 属性是什么函数,通过 name 属性,从实例得到构造函数的名称。

function Foo() {}

var f = new Foo();
f.constructor.name; // "Foo"
💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEJavaScript constructor 属性与原型详解加载中