我想在构造函数上实现一个extend方法,并用它来初始化一个实例,如:
var view_instance = View.extend()
所以我尝试了这个:
define(function (require, exports, module) {
function View(size, color) {
this.size = size;
this.color = color;
};
View.prototype = {
show: function () {
console.log("This is view show");
}
}
View.extend = function (props) {
var tmp = new this("12", "red");
console.log(this);
console.log(tmp instanceof this) //true
console.log(tmp.prototype); //undefined!
return tmp
}
return View;
})
在上面的extend
方法中,我通过new this()
初始化了一个实例,但我无法记录其原型,并检查this
是否正确。
我的代码出了什么问题?为什么原型会消失?我该怎么办呢?
答案 0 :(得分:1)
tmp.constructor.prototype
就是你想要的。 o.__proto__
只是o.constructor.prototype
和it's non-standard的快捷方式。
[编辑]
您可以在此question中看到该图。它表明Foo.prototype.constructor
指向Foo
本身。但是,由于您使用行View.prototype = {...}
覆盖构造函数的原型,View.prototype.constructor
将function Object() { [native code] }
而不是View
本身。 因此,更准确的方法是直接为原始原型分配属性,或者手动设置constructor
属性来覆盖它:
// Assign properties to the original prototype to prevent overwriting the `constructor` properties.
View.prototype.show = function() {};
// Or set the constructor manually.
View.prototype = {
show: function() {},
constructor: View
};
答案 1 :(得分:1)
您的代码没有任何问题。它做了它应该做的事情。 prototype
属性仅存在于函数中。
当您使用new
关键字进行函数调用之前,JavaScript会创建一个继承自构造函数prototype
的对象。
简单来说:
function F() {} // we have a constructor
var o = new F; // we create an instance
console.log(Object.getPrototypeOf(o) === F.prototype); // o inherits from
// F.prototype
JavaScript中的对象通过委托从其他对象继承。这意味着我们尝试访问上面看到的对象o
上的属性:
o
本身找到该属性。o
找不到该属性,则会尝试在Object.getPrototypeOf(o)
上找到该属性(或者更简洁地o.__proto__
)。 o
的原型是F.prototype
。F.prototype
找不到该属性,则会尝试在F.prototype.__proto__
Object.prototype
上找到该属性。Object.prototype
找不到该属性,那么它会放弃,因为Object.prototype.__proto__
是null
。简而言之,这就是原型继承。
您的代码为undefined
记录tmp.prototype
的原因是tmp
没有任何名为prototype
的属性。只有函数具有prototype
属性。试试这个:
console.log(Object.getPrototypeOf(tmp));
以上与以下相同。但是,不推荐使用对象的__proto__
属性。使用它需要您自担风险:
console.log(tmp.__proto__);
如果您想了解有关继承的更多信息,请阅读以下文章:
答案 2 :(得分:0)
prototype
属性属于构造函数。实例具有指向同一对象的非标准__proto__
属性。所以:
console.log(tmp.__proto__);
或者:
console.log(Object.getPrototypeOf(tmp));