網站搜尋

如何覆寫 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