Cos'è "Questo" in javascript
"Questo" in javascript è una delle domande più importanti e più frequenti in javascript.
Molte volte, a causa della scarsa comprensione del concetto, tendiamo a scrivere e incontrare bug nel nostro software. In questo articolo cercheremo di demistificare questo argomento.
Per decidere il legame di "questo", ci sono poche regole che dobbiamo capire. Quindi, prima di saltare alla risposta, basta guardare e pensare a come la funzione viene invocata o chiamata.
Elencherà le regole che renderanno facile decidere il "vincolo" di questo.
Tipo di rilegatura "Questo".
Associazione predefinita:
Quando chiamiamo o invochiamo normalmente una funzione, verrà applicata l'associazione Rule of Default. Di default in caso di “finestra” del browser fare riferimento a questo.
Capiamolo con un esempio
function foo(){
console.log(this);
function bar(){
console.log(this);
}
bar()
}
foo()
// both of the console statement will print the window.
//because , here functions are invoked normally.
// even bar is being called inside function foo.
Legame implicito:
Il secondo tipo di associazione è l'associazione "implicita". Ricordi qualche volta che chiami la funzione con (.) (punto) ? come foo.bar(). Sì, questo si chiama legame implicito. In questo caso "this" si riferisce all'oggetto chiamante.
function foo(){
console.log(this)
}
const obj = {foo: foo}
obj.foo() // prints obj as this
function foo(){
console.log(this);
function bar(){
console.log(this);
}
bar()
}
const obj = {foo: foo}
obj.foo() // what do you think? function bar will print?
Ma ricorda, quello che abbiamo imparato al punto 1, che se la funzione viene chiamata normalmente, non importa dove è definita e dove viene chiamata, "this" farà sempre riferimento al "Default Binding".
quindi qui , foo ha "obj" come this , perché obj sta chiamando . Ma "bar" viene ancora richiamato normalmente, quindi per bar(), "this" è ancora "window".
La priorità dell'associazione implicita è superiore all'associazione predefinita .
Associazione esplicita:
Quando invochiamo qualsiasi funzione usando "call", "apply" o "bind" , allora si tratta di binding esplicito. Perché qui stiamo passando "questo" oggetto in modo esplicito.
function foo(){
console.log(this)
}
const obj = {name: 'Javascript'}
foo.call(obj) // here we are passing obj as "thisArg" so now foo has "obj" as
//this binding
La priorità dell'associazione esplicita è persino superiore all'associazione implicita, ad esempio:
function foo(){
console.log(this)
}
const obj = {name: 'Javascript', foo: foo}
const obj1 = {name: 'HackerNoon'}
obj.foo.call(obj1) // Here "call" has more precedence over (.) dot.
// so now foo has obj1 as this binding
Quale pensi che sarebbe l'output per l'esempio seguente?
function foo(){
console.log(this)
}
const obj = {name: 'Javascript', foo: foo}
const obj1 = {name: 'HackerNoon'}
obj.foo.call(null)
Nuovo legame:
Quando abbiamo richiamato qualsiasi funzione con la "nuova" tastiera, molte cose accadono sotto il cofano.
- Viene creato un nuovo oggetto vuoto.
- prototipo di questo oggetto è legato al prototipo della funzione costruttore
- esegue la funzione di costruzione, legando l'oggetto "appena creato" come "questo"
- obj viene restituito , se non viene restituito nient'altro
function Foo(bar1, bar2) {
this.bar1 = bar1;
this.bar2 = bar2;
console.log(this)
}
const obj = new Foo('bar1', 'bar2')
La precedenza del "nuovo" binding è ancora più alta rispetto al binding "esplicito" o "implicito". Ad esempio:
function Foo(bar1, bar2){
this.bar1 = bar1;
this.bar2 = bar2;
console.log(this)
}
const obj = {foo: Foo}
new obj.foo('bar1', 'bar2')
//output : {bar1: 'baar1', bar2: 'bar2'}
Funzione freccia (ES6):
La funzione freccia si comporta in modo leggermente diverso dalla funzione normale. Le regole che abbiamo discusso finora non funzionano per la funzione Arrow.
La funzione freccia non ha il proprio legame "questo", quindi prende "questo" dall'ambiente più vicino che ha questo legame e, se non esiste tale env. "questo" fa sempre riferimento a "finestra" nel browser per la funzione freccia .
function foo(){
const es6 = () => console.log(this);
function normal(){console.log(this)};
es6();
normal();
}
foo()
cambiamo il modo in cui viene chiamato "foo".
function foo(){
const es6 = () => console.log(this); // obj
function normal(){console.log(this)}; // window
es6();
normal();
}
const obj = {foo: foo}
obj.foo()
So when deciding the “this” for arrow function, just look , if outside environment has any “this” binding , if yes then that’s the this binding for es6 function, if not then “window” would be the answer in browser context
const obj = {foo: () => console.log(this)}
obj.foo()
Fai una pausa, la regola dell'associazione implicita non funzionerà qui, perché foo ora è la funzione es6.
poiché non c'è nessun altro legame, perché foo non è all'interno di nessuna funzione normale che abbia il proprio "questo".
L'associazione di "questo" è "finestra" per ora.
Quindi in sort , quando dobbiamo controllare "this", guarda come la funzione viene invocata non dove la funzione è definita.

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































