Jak přepsat funkci JavaScriptu
Snažím se přepsat vestavěnou funkci parseFloat v JavaScriptu.
Jak bych to měl udělat?
Odpověď č. 1
var origParseFloat = parseFloat;
parseFloat = function(str) {
alert("And I'm in your floats!");
return origParseFloat(str);
}
Odpověď č. 2
Můžete přepsat jakoukoli vestavěnou funkci jednoduše tím, že ji znovu deklarujete.
parseFloat = function(a){
alert(a)
};
Nyní parseFloat(3) zobrazí 3.
Odpověď č. 3
Mohl byste ji přepsat, nebo raději rozšířit její implementaci takto
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);
A zavolejte to, jak byste to obvykle volali:
var result = parseFloat(1.345); // It should log the value 1.345 but get the value 0.345
Odpověď č. 4
Můžeš to udělat takto:
alert(parseFloat("1.1531531414")); // alerts the float
parseFloat = function(input) { return 1; };
alert(parseFloat("1.1531531414")); // alerts '1'
Podívejte se na funkční příklad zde: http://jsfiddle.net/LtjzW/1/
Odpověď č. 5
Přepsání je koncept, který pochází z objektově orientovaného programování, kde se dědičnost používá k rozšíření metod třídy
JavaScript má třídy (a dědičnost pomocí prototypů), ale parseFloat je jednoduše funkce a není to třída (ani prototyp). Takže byste buď museli udělat z parseFloat metodu třídy, nebo přepsat související metodu Number.parseFloat.
Pojďme to prozkoumat podrobněji. Přepisovací metoda nemění (nerozšiřuje ani nepřepisuje) původní metodu rodiče. Jak je ukázáno v následujícím příkladu:
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
Chcete-li to aplikovat na Number.parseFloat, můžeme udělat:
class B extends Number {
// overrides `parseFloat` from Number class
parseFloat() {
super.parseFloat();
}
}
const b = new B();
b.parseFloat();
Moderní praxí je však upřednostňovat kompozici před objektově orientovaným dědičstvím.
Dědičnost je považována za matoucí, křehkou a méně flexibilní ve srovnání s kompozicí. Programovací jazyky React (Facebook) a Go (Google) například oba podporují kompozici:
- https://reactjs.org/docs/composition-vs-inheritance.html#tak-co-s-dedicstvim
- https://go.dev/doc/faq#inheritance
- https://go.dev/doc/faq#overloading
Proto je moje základní doporučení používat kompozici:
const parseFloatOverride = function () {
return parseFloat();
};
A moje rozšířené doporučení je používat kompozici s injektáží závislostí, aby vznikly volně propojené závislosti, které jsou vhodnější pro unit testování.
// Inject the `Number` dependency
const parseFloatOverride = function (Number number) {
return number.parseFloat();
};
Varování: nepřepisujte základní knihovnu Javascriptu
Také téměř každá odpověď v tomto vlákně přepisuje funkci parseFloat. To je špatná praxe, protože (a) vývojáři očekávají, že parseFloat bude fungovat podle dokumentace, a (b) to zahrnuje vývojáře, kteří napsali jakékoli balíčky třetích stran, které můžete používat, a ty by teď byly poškozeny. Takže nepřepisujte základní knihovnu Javascriptu, místo toho používejte kompozici nebo dědičnost.
const parseFloat = function () {}; // Bad practice
const Number.prototype.parseFloat = function () {}; // Also bad practice
