如何覆盖javascript函数

Riz*_*Riz 90 javascript

我试图在js中覆盖内置的parseFloat函数.我该怎么做呢?

Dav*_*ers 211

var origParseFloat = parseFloat;
parseFloat = function(str) {
     alert("And I'm in your floats!");
     return origParseFloat(str);
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于备份原始的`parseFloat` (55认同)
  • @David请记住,函数被提升,这意味着`origParseFloat`指向你刚才声明的函数.[这](http://jsfiddle.net/huZG2/2/)可行. (11认同)
  • @David Waters:我担心你当前的代码会在Chrome中永远提醒. (2认同)

Roc*_*mat 39

您可以通过重新声明来覆盖任何内置函数.

parseFloat = function(a){
  alert(a)
};
Run Code Online (Sandbox Code Playgroud)

现在parseFloat(3)会提醒3.

  • 这不是函数覆盖,而是完全覆盖。 (3认同)

Ana*_*nis 9

您可以覆盖它,或者最好像这样扩展它的实现

parseFloat = (function(_super) {
    return function() {
        // Extend it to log the value for example that is passed
        console.log(arguments[0]);
        // Or override it by always subtracting 1 for example
        arguments[0] = arguments[0] - 1;
        return _super.apply(this, arguments);
    };         

})(parseFloat);
Run Code Online (Sandbox Code Playgroud)

并按通常的方式调用它:

var result = parseFloat(1.345); // It should log the value 1.345 but get the value 0.345
Run Code Online (Sandbox Code Playgroud)


Kyl*_*ild 8

你可以这样做:

alert(parseFloat("1.1531531414")); // alerts the float
parseFloat = function(input) { return 1; };
alert(parseFloat("1.1531531414")); // alerts '1'
Run Code Online (Sandbox Code Playgroud)

在这里查看一个工作示例:http://jsfiddle.net/LtjzW/1/


tfm*_*gue 8

覆盖是来自面向对象编程的概念,其中继承用于扩展类方法

Javascript 有类(和原型继承),但parseFloat只是一个函数而不是类(或原型)。因此,您要么需要创建parseFloat一个类方法,要么重写相关Number.parseFloat方法。

让我们进一步探讨这一点。重写方法不会改变(扩展或覆盖)原始父方法。如下例所示:

class A {
  // parent method
  print() {
    console.log("class A");
  }
}

class B extends A {
  // override method
  print() {
    console.log("class B");
  }
  parentPrint() {
    super.print();
  }
}

const b = new B();
b.print(); // prints "class B" from override method
b.parentPrint(); // prints "class A" from parent method
Run Code Online (Sandbox Code Playgroud)

要将其应用到Number.parseFloat,我们可以这样做:

class B extends Number {
  // overrides `parseFloat` from Number class
  parseFloat() {
    super.parseFloat();
  }
}

const b = new B();
b.parseFloat();
Run Code Online (Sandbox Code Playgroud)

然而,现代实践更倾向于组合而不是面向对象的继承。

与组合相比,继承被认为是混乱的、脆弱的且灵活性较差。例如,React (Facebook) 和 Go (Google) 编程语言都鼓励组合:

因此我的基本建议是使用组合:

const parseFloatOverride = function () {
  return parseFloat();
};
Run Code Online (Sandbox Code Playgroud)

我的扩展建议是使用组合与依赖项注入,以创建更适合单元测试的松散耦合依赖项。

// Inject the `Number` dependency
const parseFloatOverride = function (Number number) {
  return number.parseFloat();
};
Run Code Online (Sandbox Code Playgroud)

警告:不要覆盖 Javascript 核心库

此外,该线程上的几乎每个答案都会覆盖该parseFloat函数。这是不好的做法,因为(a)开发人员希望parseFloat按照记录的方式工作,并且(b)包括编写您可能使用的任何第三方软件包的开发人员,这些软件包现在可能会被损坏。因此,不要覆盖 Javascript 核心库,而是使用组合或继承。

const parseFloat = function () {}; // Bad practice
const Number.prototype.parseFloat = function () {}; // Also bad practice
Run Code Online (Sandbox Code Playgroud)