Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erklärung der Verwendung in Javascript

Ausführliche Erklärung der Verwendung in Javascript

不言
不言nach vorne
2019-03-23 09:36:422419Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Erklärung der Verwendung in Javascript. Freunde in Not können darauf verweisen.

Bevor Sie dies in Javascript verstehen, verstehen Sie zunächst den Umfang.

Bereiche werden in zwei Typen unterteilt:

1. Lexikalischer Bereich: Die Engine sucht nach Variablen mit Namensbezeichnern im aktuellen Bereich oder in verschachtelten Unterbereichen. (Wie und wo die Engine sucht. Der Definitionsprozess findet während der Code-Schreibphase statt)
2. Dynamischer Bereich: Der Bereich wird zur Laufzeit dynamisch bestimmt.

Der Unterschied zwischen lexikalischem Bereich und dynamischem Bereich ist: Der lexikalische Bereich wird beim Schreiben von Code oder die Definition des dynamischen Bereichs zur Laufzeit bestimmt.

Bindungsregeln dafür

Dies wird beim Aufruf gebunden, abhängig vom Aufrufort der Funktion. Daraus lässt sich erkennen, dass dies unter normalen Umständen (im nicht strengen Modus) das Objekt entsprechend dem Kontext des Funktionsaufrufs (Aufrufstapel) bindet.

1. Standardbindung

Standardbindung: Standardbindung bedeutet, dass im nicht-strikten Modus und ohne andere Bindungsregeln die Funktion entsprechend dem zu bindenden Kontext (Aufrufstapel) aufgerufen wird Objekte (globale Objekte). (Im strikten Modus ist undefiniert gebunden)

Zum Beispiel:

function foo() {
    console.log(this.a);
};
function bar() {
    var a = 3;
    foo();
}
var a = 2;
bar();  //调用栈在全局作用域,this绑定全局对象

运行结果为: 2
//加上"use strict"运行结果则会变成this is undefined

Wenn die Funktion hier aufgerufen wird, wird die Standardbindung verwendet und der Kontext des Funktionsaufrufs (Aufrufstapel) ist der globale Geltungsbereich, daher ist dieser an das globale Objekt (global) gebunden.

eg2:
function foo() {
    console.log(this.a)
};
var a = 2;
(function() {
    "use strict"
    foo();
})();

运行结果为: 2

Hier ist zu beachten: Bei der Standardbindung bestimmt nicht, ob sich die aufrufende Position im strikten Modus befindet, sondern ob sich der Funktionskörper im strikten Modus befindet (falls der Funktionskörper in ist). Im strengen Modus ist diese Bindung undefiniert. Andernfalls ist sie an das globale Objekt gebunden. Außerdem: Obwohl es möglich ist, den strengen Modus und den nicht strengen Modus zu binden, ist es am besten, sie nicht zu mischen.

Indirekte Verweise wenden im Allgemeinen Standardbindungsregeln an.

eg:
function foo() {
    console.log(this.a);
};
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo();   //3
(p.foo = o.foo)();  //2

Der Rückgabewert des Zuweisungsausdrucks p.foo = o.foo bezieht sich direkt auf die Zielfunktion foo.

2. Implizite Bindung

Implizite Bindung: Vom Kontextobjekt aufgerufen, an das Kontextobjekt gebunden.

Zum Beispiel:

function foo() {
    console.log(this.a);
};
var obj = {
    a: 2,
    foo: foo
};
obj.foo();    //2
foo();        //undefined

In diesem Code wird foo() als Referenzattribut zum obj-Objekt hinzugefügt. Wenn obj diese Referenzattributfunktion aufruft, wird der Referenzattributkontext verwendet. Dies wird an das Objekt obj gebunden. (Genau genommen gehört diese Funktion nicht zum obj-Objekt, sondern dient nur als Referenzattribut.) Gehört zur impliziten Bindung.

Die direkte Ausführung der Funktion foo() unten ist kein Verweis auf das obj-Objekt, daher ist das Kontextobjekt das globale Objekt. Daher ist dies an undefiniert gebunden. Gehört zur Standardbindung.

Nur ​​die obere oder letzte Ebene in der Objektreferenzkette spielt beim Aufrufort eine Rolle.

Hinweis:

Implizit gebundene Funktionen verlieren das gebundene Objekt. Zu diesem Zeitpunkt wird die Standardbindung angewendet und diese an das globale Objekt oder undefiniert gebunden, je nachdem, ob es sich im strikten Modus befindet.
zB:

function foo() {
    console.log(this.a);
};
var obj = {
    a: 2;
    foo: foo
}
var bar = obj.foo;
var a = 'biubiubiu';
bar();

运行结果:"biubiubiu"

Analyse: Es scheint, dass bar ein Verweis auf obj.foo ist. Tatsächlich bezieht sich bar direkt auf die Funktion foo, bei der es sich um einen einfachen Funktionsaufruf handelt, es handelt sich also tatsächlich um die Standardbindung .

Die Parameterübergabe ist eine implizite Zuweisung. Wenn sie also an die Funktion übergeben wird, wird sie auch implizit zugewiesen.
zB:

function foo() {
    console.log(this.a);
};
var obj = {
    a: 2,
    foo: foo
};
function bar(fn) {
    fn();
};
var a = "biubiubiu";
bar(obj.foo);

运行结果: "biubiubiu"

Analyse: Tatsächlich werden die Parameter auch implizit zugewiesen, aber die Parameter werden an die Funktion übergeben und in der Funktion ausgeführt. Zu diesem Zeitpunkt wird auch direkt auf die Funktion foo verwiesen, sodass es sich ebenfalls um einen einfachen Funktionsaufruf unter Verwendung der Standardbindung handelt.

Übergeben Sie Funktionen an in die Sprache integrierte Funktionen. (Im Grunde ähnlich wie in der obigen Situation, ändern Sie die selbstdeklarierte Funktion in die integrierte Funktion der Sprache.) Es kommt häufig vor, dass Rückruffunktionen dies verlieren, und die Funktion, die die Rückruffunktion aufruft, kann dies möglicherweise verlieren Ändern Sie dies auch.

3. Explizite Bindung

Explizite Bindung: Binden Sie dies direkt an das angegebene Objekt. Die meisten Funktionen in Javascript und von Ihnen erstellte Funktionen können diese beiden expliziten Bindungsmethoden verwenden.

1, .call()
2, .apply()
Diese beiden Bindungsmethoden, der erste Parameter ist das daran gebundene Objekt. (Wenn der übergebene Parameter ein primitiver Wert ist (String-Typ, boolescher Typ, numerischer Typ), wird der primitive Wert in eine Objektform (neuer String, neuer Boolescher Wert, neue Zahl) konvertiert. Dies ist genannt: Boxen)

Zum Beispiel:

function foo() {
    console.log(this.a);
};
var obj = {
    a: 2
};
foo.call(obj);

运行结果: 2

Die Anzeige der Bindung löst jedoch nicht das Problem des Bindungsverlusts. Zu dieser Zeit kommt ein neuer Freund – die harte Bindung (bind).

3. .bind() (Feste Bindung ist ein häufiges Szenario, daher stellt es5 die integrierte Methode Function.prototype.bind bereit.)
bind() will Gibt eine neue Kodierungsfunktion zurück, bindet diese an die angegebenen Parameter und ruft die Funktion auf.

Zum Beispiel:

function foo(e) {
    console.log(this.a + e);
    return this.a + e;
};
var obj = {
    a: 2
}
var bar = foo.bind(obj); //新编码函数
var b = bar(3); // 2 3
console.log(b); // 5

bind() Es gibt auch eine -Funktion : wird bis auf die erste verwendet Ein anderer Parameter als die daran gebundenen Parameter werden an die zugrunde liegende Funktion übergeben ( gilt teilweise , was eine Art „Currying “ ist).

这里涉及到一个概念:把null或者undefined作为this的绑定对象传入call、apply、bind,这些值在调用的时候会被忽略,实际应用默认绑定规则。
应用场景:
1、使用apply()展开一个数组,并作为参数传递给一个函数。
2、bind()对参数进行柯里化(预先设置一些参数)。

举个栗子:

function foo(a,b) {
    console.log("a:" + a + ",b:" + b);
};
//数组“展开”成参数
foo.apply(null,[2,3]);  //a:2,b:3
//bind()柯里化
var bar = foo.bind(null,2);
bar(3);  //a:2,b:3

解析:传入一个参数作为this绑定对象,如果不传则使用占位符(null),此时会使用默认绑定规则。

上面这个例子可能会产生一定的副作用,如果需要运用这种场景并且更加安全。可以创建一个空对象(可以用任意喜欢的名字来命名)。

var ∅ = Object.create(null);
//上面这个例子就可以改写为:
foo.apply(∅,[2,3]); //a:2,b:3
var bar = foo.bind(∅,2);
bar(3);  //a:2,b:3

注意:硬绑定之后不能使用隐式绑定和显式绑定对this进行修改
在这里介绍一种软绑定的方法softBind()检查this绑定到全局对象或者undefined后,绑定this到指定的默认对象。绑定后效果和硬绑定一样,但是保留隐式绑定或者显式绑定修改this的能力。

四、new绑定

Javascript中的new机制与面向类语言的完全不同。在Javascript中,构造函数只是一些使用new操作符时被调用的函数,不属于一个类,也不会实例化一个类。称为对函数的“构造调用”。

举个栗子:

function foo(a) {
    this.a = a;
}
var bar = new foo(2);
console.log(bar.a); //2

使用new的过程会创建一个全新的对象,this会绑定这个新对象。如果函数没有返回其他对象,则new表达式函数调用会返回该新对象。(这个新对象会连接prototype)

四种绑定规则的优先级为:new>显式>隐式>默认

箭头函数

箭头函数是根据外层作用域(函数或全局)来决定this。(词法作用域取代this机制)
箭头函数this会绑定调用时的对象,且箭头函数的绑定无法修改(new也不行)。

其实可以理解为,箭头函数的this在词法上继承的是它所在的作用域(函数或全局)的this,而它继承的函数作用域的this绑定的是在该函数调用上下文对象,所以箭头函数的this间接的绑定在调用上下文对象。

简述: 箭头函数this(绑定作用域this)-- 作用域this(绑定在调用上下文对象)。

故:箭头函数this == 调用的上下文对象

举个栗子:

function foo() {
    setTimeout(function() {
        //这里的this在词法上继承自foo()
        console.log(this.a);
    },100);
};
var obj = { a: 2 };
foo.call(obj);  //2

其实这个栗子也等价于:

function foo() {
    var that = this;  //lexical capture of this
    setTimeout(function() {
        console.log(self.a)
    },100);
}
...与上面一样

所以,有两种风格:this风格(四种规则)词法作用域风格(that = this和箭头函数)可供使用。使用时尽量避免混用,否则会造成难以维护的后果。

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung der Verwendung in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen