【问题标题】:Javascript does not call prototype methodJavascript 不调用原型方法
【发布时间】:2016-09-01 01:27:26
【问题描述】:

我尝试重写一个方法,脚本是:

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();

结果是“在包装中”。不知道为什么?

【问题讨论】:

  • Modelobjectobject 不能有 2 个同名的键!
  • @Rayon: shadow,而不是 override,使用更好的术语。 OP 没有将属性分配给 Model 两次,而是分配给 Model 和原型。
  • @JeremyJStarcher, True.. override 一词会误解..

标签: javascript prototype private


【解决方案1】:

任何 JavaScript 对象都有自己的继承的属性。 Own 是直接在实例上定义的,inherited 取自 prototype 对象。
当使用属性访问器时,JavaScript 首先搜索对象的自己的属性列表。如果未找到该属性,则在对象的原型链中搜索。

在您的示例中,wrapper() 方法在对象实例上定义了一个自己的属性doABC,这是一个提醒'in wrapper' 的函数。即使该对象的原型具有与提醒'in Model' 相同的属性doAbc,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

【讨论】:

  • 感谢您的回答!
  • 我尝试调试该脚本。在运行 target.doABC 语句之前,对象 a 已经具有来自原型的 doABC() 方法。运行 target.doABC 后,该函数被更新。
  • @user3468795 是的,它在构造函数中以这种方式发生。我的回答是针对问题The result is 'in wrapper'. I don't know why?
【解决方案2】:

让我看看能不能解释一下:

这里有两个不同版本的doABC

您的target.doABC 创建一个特定于那个您的Model 实例的函数,每个Model 都有自己的doABC

因为Model 有一个doABC,JavaScript 引擎不需要“向上”查找其他内容,因此它永远不会查找Model.prototype.doABC 版本。

您可以通过添加以下几行来看到这一点:

Model.prototype.doXYZ = function () {
    alert('in Model');
};

并调用

a.doXYZ();

由于a没有自己的doXYZ,那么只有这样,它才会查找链并查看原型中的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 2012-02-05
    • 1970-01-01
    相关资源
    最近更新 更多