obj2.prototype.constructor = obj;
完整的代码:
var obj = function () {
this.str = "hello world!.";
obj.prototype.printTxt = function () {
console.log(this.str);
};
};
var obj2 = function () {
this.str = "Good bye";
};
obj2.prototype = new obj;
obj2.prototype.constructor = obj;
答案 0 :(得分:1)
constructor
属性只是JavaScript中的约定 (从ES2015开始不再是这样);它指向与constructor
属性所在的原型相关联的函数。那是一个令人费解的句子,所以:假设一个函数Foo
。 Foo.prototype.constructor
将为Foo
。同样,假设var f = new Foo();
,f.constructor
将为Foo
。
对于JavaScript标准中的任何内容,它实际上并不是 。 (从ES2015开始,就像各种Promise
方法一样。) 这只是一个约定,除非有人搞砸了(这很容易),一个对象将拥有一个constructor
属性,它继承自其原型,即用于创建它的函数。
我说这很容易打破,因为,好吧,人们经常这样做。以下是打破它的一个例子:
function Foo() {
}
Foo.prototype = {
bar: function() {
}
};
var f = new Foo();
console.log(f.constructor === Foo); // false
您引用的代码对于JavaScript非常不寻常:
最重要的是,它打破了一条非常重要的规则:您不会在构造函数中更改原型的属性(非常边缘情况除外)。 (虽然在这种特殊情况下,它是以无害但毫无意义的方式进行的。)
它打破了JavaScript中的基本命名规则:构造函数以大写字母开头(Obj
,而不是obj
)。
它显示了一种用于设置继承层次结构的一种非常普遍但基本上已经破碎的模式。
所以总的来说,我可能不会使用你从中得到代码的任何资源。
FWIW,这是该代码的更正版本:
function Base() {
this.str = "hello world!.";
}
Base.prototype.printTxt = function () {
console.log(this.str);
};
function Derived() {
this.str = "Good bye";
}
Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;
Object.create
由ECMAScript5定义。它的单参数版本可以为旧引擎(它的多参数版本不能)进行填充,如下所示:
if (!Object.create) {
Object.create = function(proto) {
if (arguments.length > 1) {
throw "The multi-argument version of Object.create cannot be shimmed.";
}
function ctor() { }
ctor.prototype = proto;
return new ctor();
};
}