揭开JS中constructor的秘密

34次阅读

共计 2280 个字符,预计需要花费 6 分钟才能阅读完成。

学习 js 原型与继承的时候,经常会碰到 constructor,现在来揭开神秘面纱
描述:所有对象都会从它的原型上继承一个 constructor 属性
var o = new Object;
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var a = new Array;
a.constructor === Array // true

var n = new Number(3);
n.constructor === Number; // true
继承中的 constructor
function Person (name, age) {
this.name = name,
this.age = age
}
Person.prototype.setAge = function () {
console.log(“111”)
}
function Student (name, age, price) {
Person.call(this, name, age)
this.price = price
this.setScore = function () {}
}
Student.prototype = Object.create(Person.prototype)// 用于设置原型
Student.prototype.constructor = Student// 重新分配原始构造函数
var s1 = new Student(‘Tom’, 20, 15000)
console.log(s1 instanceof Student, s1 instanceof Person) // true true
s1.setAge() // 111
console.log(s1)
console.log(s1.constructor) //Student

现在不手动重置构造函数
function Person (name, age) {
this.name = name,
this.age = age
}
Person.prototype.setAge = function () {
console.log(“111”)
}
function Student (name, age, price) {
Person.call(this, name, age)
this.price = price
this.setScore = function () {}
}
Student.prototype = Object.create(Person.prototype)// 用于设置原型
// Student.prototype.constructor = Student// 重新分配原始构造函数
var s1 = new Student(‘Tom’, 20, 15000)
console.log(s1 instanceof Student, s1 instanceof Person) // true true
s1.setAge() // 111
console.log(s1)
console.log(s1.constructor) // Person
可以看到除了 s1 的 constructor 不同,重置不重置原始构造函数对我们的继承没有影响。
结论就是:constructor 是用于识别对象是由哪个构造函数初始化的, 对继承没影响可以看这篇文章:JS constructor 探讨(一): 为什么要设置 prototype.constructor?
But!!什么情况下要手动重置构造函数???那就是你要调用 constructor() 的时候!!!此时 constructor 的指向就会产生影响
来一个 MDN 上的列子:
function Parent() {};
function CreatedConstructor() {}

CreatedConstructor.prototype = Object.create(Parent.prototype);

CreatedConstructor.prototype.create = function create() {
return new this.constructor();
}

new CreatedConstructor().create().create();

为什么报错,因为 CreatedConstructor.prototype.constructor 为 Parent,所以 new CreatedConstructor().create() 的结果是 Parent{} 这个对象,这个对象没有 create 方法,所以报错了
解决办法:
function Parent() {};
function CreatedConstructor() {}

CreatedConstructor.prototype = Object.create(Parent.prototype);
CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using

CreatedConstructor.prototype.create = function create() {
return new this.constructor();
}

new CreatedConstructor().create().create(); // it’s pretty fine

这时候需要重置 CreatedConstructor 的构造函数,使 constructor 重新指向自己
参考文章:JS constructor 探讨(一): 为什么要设置 prototype.constructor?Object​.prototype​.constructor

正文完
 0