如何覆盖 JavaScript 函数

我正在尝试覆盖 JavaScript中内置的 parseFloat函数。

我该怎么做呢?

255835 次浏览

你可以这样做:

alert(parseFloat("1.1531531414")); // alerts the float
parseFloat = function(input) { return 1; };
alert(parseFloat("1.1531531414")); // alerts '1'

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

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

只需重新声明它,就可以覆盖任何内置函数。

parseFloat = function(a){
alert(a)
};

现在 parseFloat(3)将警报3。

您可以覆盖它,或者最好是 延伸,它的实现如下所示

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

就像你平时说的那样:

var result = parseFloat(1.345); // It should log the value 1.345 but get the value 0.345

覆盖是一个来自面向对象程序设计的概念,其中继承被用来扩展类方法

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

为了将这种方法应用到 Number.parseFloat,我们可以这样做:

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


const b = new B();
b.parseFloat();

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

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

因此,我的基本建议是使用复合体:

const parseFloatOverride = function () {
return parseFloat();
};

我的推荐是使用带依赖注入的组合,创建更适合单元测试的松散耦合依赖关系。

// Inject the `Number` dependency
const parseFloatOverride = function (Number number) {
return number.parseFloat();
};

警告: 不要覆盖 Javascript 核心库

此外,这个线程上的几乎每个答案都会覆盖 parseFloat函数。这是一种糟糕的做法,因为(a)开发人员希望 parseFloat按文档化的方式工作,(b)包括编写了您可能使用的任何第三方软件包的开发人员在内的 parseFloat现在已经损坏。因此,不要覆盖 Javascript 核心库,而是使用组合或继承。

const parseFloat = function () {}; // Bad practice
const Number.prototype.parseFloat = function () {}; // Also bad practice