Vyhledávání na webu

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

Související články