In questo caso specifico, ci si assegna il metodo per String.prototype
, in questo modo:
String.prototype.SayHi = function SayHi() {
return "Hi " + this + "!";
};
o meglio come una proprietà non enumerabile utilizzando Object.defineProperty
(ES5 e più alto, in modo sostanzialmente, tutto, ma IE8 e precedente):
Object.defineProperty(String.prototype, "SayHi", {
value: function SayHi() {
return "Hi " + this + "!";
}
});
JavaScript è un linguaggio prototipo. Ciò significa che ogni oggetto è supportato da un oggetto prototipo . In JavaScript, questo prototipo viene assegnato dalla funzione di costruttore per l'oggetto o dalla nuova funzione (ish) ECMAScript5 Object.create
.
Nel primo caso (la funzione di costruzione), il prototipo assegnato a un oggetto è definito dalla proprietà prototype
della funzione di costruzione. Quindi, se avete una funzione di costruzione chiamato Foo
:
function Foo() {
}
... allora l'istruzione
var f = new Foo();
... assegna Foo.prototype
all'istanza f
come oggetto prototipo. Così:
function Foo(b) {
this.baz = b;
}
Foo.prototype.bar = function bar() {
console.log(this.baz);
};
var f = new Foo("Charlie");
f.bar(); // logs "Charlie"
Quindi nel tuo esempio, dal momento che firstName
è un'istanza String
(in realtà una stringa primitiva, ma non preoccupatevi, si ottiene automagicamente promosso a un'istanza String
quando necessario), il suo prototipo è String.prototype
, così l'aggiunta di una proprietà a String.prototype
che fa riferimento alla funzione SayHi
rende tale funzione disponibile su tutte le istanze String
.
Come DougR sottolineato in un commento, una differenza da C# i metodi di estensione è che i metodi di estensione C# s 'can be called on null
references (se si dispone di un metodo string
estensione, string s = null; s.YourExtensionMethod();
funziona in realtà). Questo non è vero con JavaScript; null
è un tipo proprio e non esiste un prototipo da estendere per questo.
Una breve nota sui nomi di funzione in questi esempi, ad es.
Object.defineProperty(String.prototype, "SayHi", {
value: function SayHi() {
// HERE ------------^
return "Hi " + this + "!";
}
});
Foo.prototype.bar = function bar() {
// AND HERE -----------------^
console.log(this.baz);
};
Quella forma, dove stiamo utilizzando una funzione di espressione con un nome in esso (una "funzione un'espressione nominata," aka NFE) usato per essere famosa per avere problemi (su IE8 e precedenti; e su versioni veramente vecchie di un paio di altri browser). Con tutto il resto essere morto e IE8 essendo quasi morto, non c'è più bisogno di preoccuparsi per gli NFE.(E quanto sopra sarebbe ok anche in IE8.)
@DougR: Siamo spiacenti, pulizia dei commenti standard. Quando un commento diventa obsoleto, i mod o gli utenti esperti possono rimuoverlo (i mod possono farlo direttamente, gli utenti devono collaborare nella coda di revisione). Ho aggiornato la risposta per segnalare che l'hai segnalato. :-) –
@Grundy: Grazie, sì, l'intero punto della stringa 'String s = null;' parte doveva usare 's.YourExtensionMethod()'! Apprezzo il pescato. :-) –
Grazie per aver evidenziato che il metodo di estensione funziona per entità null. – Rama