【问题标题】:JavaScript: Setting variable to new function on created object, it still calls old functionJavaScript:在创建的对象上将变量设置为新函数,它仍然调用旧函数
【发布时间】:2016-07-21 06:08:16
【问题描述】:

我有一个看起来像这样的“类”:

export function IBXMReplay() {
    var onRow = function(){console.log("not right")};
    ....
}

稍后,它会在这样的函数中调用:

var seqRow = function() {
    onRow();
    ....
}

这个函数本质上是由网络音频getAudio的回调调用的。我这样构造对象:

var replay = new IBXMReplay();
replay.onRow = function(){console.log("Right")};

但是,当 onRow() 被调用时,它总是打印"not right."

我做错了什么???我尝试创建一个 setter 函数,但也没有用。

【问题讨论】:

  • 好吧,您将 onRow 分配给对象重放的新函数。所以,如果你想让它在“seqRow”中做你想做的事,你必须做 replay.onRow()

标签: javascript function class object callback


【解决方案1】:

问题是onRow 函数被定义为IBXMReplay 局部范围内的变量,我假设seqRow 函数也在IBXMReplay 内。局部范围的变量不能从外部直接访问或修改。

为此,您需要将onRow 函数设为IBXMReplay 对象的属性(在JS 函数中也是对象):

export function IBXMReplay() {
    this.onRow = function(){console.log("not right")};
    ....
}

或者更好的是,将其存储在原型中

var IBXMReplay = function IBXMReplay() {
    ....
}
IBXMReplay.prototype.onRow = function(){console.log("not right")};
export IBXMReplay

不管怎样,你以后可以这样做:

var replay = new IBXMReplay();
replay.onRow = function(){console.log("Right")};

它应该可以按您的预期工作。


现在,对此进行一些解释。假设您有 100 个 IBXMReplay 'class' 实例。将其存储为对象属性与原型属性之间的区别是微妙但重要的:

对象属性

this.onRow 这样存储方法意味着内存中有100 个副本。如果您稍后使用 replay.onRow = something 对其进行编辑,它将被该特定实例完全替换。

执行delete replay.onRow 之类的操作不会恢复原始函数,而是会在执行该实例时抛出“未定义不是函数”错误。

原型属性

将函数存储在对象的原型中意味着只有onRow 的一个副本被所有实例引用。当使用replay.onRow = something 编辑实例时,底层原型onRow 只是被同名的对象属性遮蔽,因此IBXMReplay 类内的任何调用都将引用覆盖函数.

删除实例属性delete replay.onRow 将“发现”原始函数。

这就是 JavaScript 的工作方式,被称为 原型链。每当您执行foo.bar 时,会直接在foo 对象中搜索bar 属性,但如果未找到则在foo 的原型中搜索它,然后在原型的原型中搜索,以此类推,直到到达@ 987654343@,没有原型。

【讨论】:

  • 感谢您的详细记录。
猜你喜欢
  • 2019-05-09
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 2013-09-26
  • 2023-04-09
相关资源
最近更新 更多