如何覆寫 JavaScript 函式
我正在嘗試覆寫內建的 parseFloat 函數在 JavaScript 中。
我該如何去做那件事?
答案#1
var origParseFloat = parseFloat;
parseFloat = function(str) {
alert("And I'm in your floats!");
return origParseFloat(str);
}
答案#2
你可以透過重新宣告來覆蓋任何內建函數。
parseFloat = function(a){
alert(a)
};
現在 parseFloat(3) 會跳出提示 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
答案#4
你可以這樣做:
alert(parseFloat("1.1531531414")); // alerts the float
parseFloat = function(input) { return 1; };
alert(parseFloat("1.1531531414")); // alerts '1'
在這裡查看一個可運行的範例:http://jsfiddle.net/LtjzW/1/
答案#5
覆寫是一個源自物件導向程式設計的概念,其中使用繼承來擴展類別方法
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)編程語言都鼓勵使用組合:
- https://reactjs.org/docs/composition-vs-inheritance.html#so-what-about-inheritance
- https://go.dev/doc/faq#inheritance
- https://go.dev/doc/faq#overloading
因此,我的基本建議是使用組合:
const parseFloatOverride = function () {
return parseFloat();
};
而我進一步的建議是使用組合與依賴注入,以建立鬆散耦合的依賴,這樣更適合單元測試。
// Inject the `Number` dependency
const parseFloatOverride = function (Number number) {
return number.parseFloat();
};
警告:請勿覆寫 Javascript 核心庫
幾乎這個討論串中的每個回答都覆寫了 parseFloat 函數。這是不好的做法,因為 (a) 開發者期望 parseFloat 按照文件正常工作,(b) 這也包括撰寫你可能使用的任何第三方套件的開發者,這些套件現在會被破壞。所以不要覆寫 Javascript 核心庫,而應使用組合或繼承。
const parseFloat = function () {}; // Bad practice
const Number.prototype.parseFloat = function () {}; // Also bad practice
