我尝试覆盖一个方法,脚本是:
function wrapper(target) {
target.doABC = function () {
alert('in wrapper');
};
return target;
}
function Model() {
wrapper(this);
}
Model.prototype.doABC = function () {
alert('in Model');
};
var a = new Model();
a.doABC();
结果是“在包装中”。我不知道为什么?
答案 0 :(得分:5)
任何JavaScript对象都有拥有和继承属性。 自己是直接在实例上定义的内容,而继承的是从prototype
对象中获取的。
使用属性访问者时,JavaScript首先搜索对象的自己的属性列表。如果找不到该属性,则会在对象的原型链中搜索。
在您的示例中,wrapper()
方法在对象实例上定义了一个自己的属性doABC
,它是一个警告'in wrapper'
的函数。即使对象具有提醒doAbc
的相同属性'in Model'
的原型,JavaScript仍然会使用自己的属性。
function wrapper(target) {
// Define an own property "doABC"
target.doABC = function () {
alert('in wrapper');
};
return target;
}
function Model() {
wrapper(this);
}
// Define an inherited property "doABC"
Model.prototype.doABC = function () {
alert('in Model');
};
var a = new Model();
//Use the own property "doABC". The inherited "doABC" is ignored.
a.doABC();
作为补充,可以使用delete
运算符删除自己的属性。删除后,该对象将使用继承的属性。
// delete the own property "doABC"
delete a['doABC'];
// the inherited "doABC" will be used. Alerts "in Model"
a.doABC();
检查完整的working demo。
答案 1 :(得分:1)
让我看看能不能解释一下:
这里有doABC
的两个单独版本。
您的target.doABC
创建了一个特定于的功能 Model
的实例,每个Model
获得了自己的doABC
。
由于Model
有一个doABC
,因此JavaScript引擎无需查看其他内容,因此它永远不会寻找Model.prototype.doABC
版本。
您可以通过添加以下行来看到这一点:
Model.prototype.doXYZ = function () {
alert('in Model');
};
并致电
a.doXYZ();
由于a
没有自己的doXYZ
,所以只有这样,它会查找链并查看原型中的方法。