【问题标题】:Decorate prototype and call parent function装饰原型并调用父函数
【发布时间】:2015-12-27 16:21:43
【问题描述】:

我正在尝试装饰一些对象,例如:

Object.prototype.someFunc = function(x) {
  if (x == 1) {
      return x;
  } 

  return super.someFunc() // <-- ? 
}

如何在第二个 return 语句中调用我要覆盖的函数?

【问题讨论】:

  • 首先,您通常不应该添加到原生对象的原型中,因为它可能会导致问题。其次,您必须将旧函数存储在临时变量中。
  • 也许在这里你应该更清楚你想用super做什么,因为它是一种访问对象父级函数的特殊方式。
  • 完全取决于您所说的“覆盖”。你要换吗?你在原型链中隐藏它吗?这就是为什么您需要对代码进行实际的、完整的演示。事实上,你的问题还不清楚。

标签: javascript


【解决方案1】:

您可以利用继承:

function Parent() { }

Parent.prototype.someFunc = function(x) {
    var result = 0;
    if (x == 1) {
        result = 1;
    }
    return result;
}

function Child() { }

Child.prototype = Object.create(Parent.prototype); //inheritance
Child.prototype.constructor = Child; //enforce the constructor to be Child instead of Parent

Child.prototype.someFunc = function(x) {
    return Parent.prototype.someFunc.call(this, x); //call your Parent prototype someFunc passing your current instance
}

var child = new Child();
console.log(child.someFunc(1)); //1
console.log(child.someFunc(2)); //0

避免扩展原生原型。见https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

【讨论】:

    【解决方案2】:
    var _someFunc = Object.prototype.someFunc;
    Object.prototype.someFunc = function(x) {
      // ...
      return _someFunc.call(this, x/*, other args*/);
    }
    

    【讨论】:

    • 您对此方法进行了静态调用。这意味着在函数中,如果您使用this,您将无法获得您正在处理的实例
    • 对。应该使用调用/应用/绑定。谢谢!
    【解决方案3】:

    您需要进行备份。说:

    var __superFunc = Object.prototype.someFunc;
    Object.prototype.someFunc = function(x) {
      if (x == 1) {
          return x;
      }
    
      return __superFunc.call(this, x);
    }
    

    【讨论】:

    • super 是保留字。
    • 是否也需要将 x 传递给 __superfunc ? __superfunc(x)
    • 我怀疑第一个会起作用。 this.prototype.someFunc 不存在。
    • 你们两个,没看到字条吗?
    • 没有。因为 1)这是你永远不应该使用的私人东西,并且 2)__proto__.someFunc 是新功能。
    【解决方案4】:

    整个代码必须重写;您还需要为父级指定函数的行为(以防止递归调用)......这是使用调用方法的解决方案的提示:

    Object.prototype.someFunc.call(this, x);
    

    在javascript中,没有真正的原生实现继承

    【讨论】:

    • Object.someFunc 并不存在。 (new Object()).someFunc 做。或Object.prototype.someFunc.
    • 所以这里还有另一个问题。当您执行 Object.prototype.someFunc = function(x) {...} 时,Object.prototype.someFunc 的值将被覆盖。在调用它之前,您已经捕获了先前的值。您的回答将导致无限循环和最大堆栈大小错误。
    • 我不明白你的评论。这段代码Object.prototype.someFunc = function(x) {...} 只完成一次,也许是在页面加载中。然后在运行时,当在 Object 的某个实例上调用 someFunc 时,我们可以执行 Object.prototype.someFunc.call(this, x); 。所以,我不明白你在哪里可以看到任何压倒一切的
    • @ikken:将您的代码放入原始代码中并进行测试。你会看到你有一个没有转义条件的递归调用。
    • 所以 OP 正在询问如何访问覆盖它的函数中的原始(或 super)函数。你最终需要两个函数。
    猜你喜欢
    • 1970-01-01
    • 2014-10-23
    • 2022-01-24
    • 2017-01-15
    • 1970-01-01
    • 2019-08-30
    • 2017-09-13
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多