Dies ist in Javascript ein völlig anderer Mechanismus als in anderen Sprachen, was einige Ingenieure, die andere Sprachen schreiben, verwirren kann.
1. Ich dachte fälschlicherweise, dass dies auf die Funktion selbst hinweist
Gemäß der englischen Grammatik ist es leicht, dieses Erscheinen in einer Funktion als die Funktion selbst zu verstehen. In JavaScript sind Funktionen erstklassige Bürger und können beim Aufruf tatsächlich Attributwerte speichern. Bei falscher Anwendung kann es jedoch zu Abweichungen von den tatsächlichen Erwartungen kommen. Informationen zu bestimmten Umständen finden Sie im folgenden Code
function fn(num){ this.count++; } fn.count = 0; for(var i=0;i<3;i++){ fn(i); } console.log(fn.count); // 0
Wenn dies in der fn-Funktion auf eine eigene Funktion verweist, sollte sich der Attributwert des count-Attributs ändern, tatsächlich bleibt er jedoch unverändert. Für dieses Problem verwenden einige Leute den Bereich, um es zu lösen, z. B. das Schreiben von
var data = { count:0 }; function fn(num){ data.count++; } for(var i=0;i<3;i++){ fn(i); } console.log(data.count); //3
Oder direkter,
function fn(num){ fn.count++; } fn.count = 0; for(var i=0;i<3;i++){ fn(i); } console.log(fn.count);//3
Obwohl beide Methoden die richtigen Ergebnisse liefern, vermeiden sie das Problem, wo dies gebunden ist. Wenn das Funktionsprinzip einer Sache nicht klar ist, führt dies häufig zu Kopfschmerzen und Schmerzen, was zu hässlichem Code und schlechter Wartbarkeit führt.
2. Diese magische Bindungsregel
2.1 Standardbindungsregeln
Die erste ist die häufigste dieser Bindung. Schauen Sie sich den Code unten an
function fn(){ console.log(window === this); //浏览器环境 } fn(); //true
Funktion fn wird ohne weitere Änderungen direkt im globalen Bereich aufgerufen. In diesem Fall wird beim Aufruf der Funktion die Standardbindung verwendet, die auf das globale Objekt verweist.
Dadurch wird deutlich, dass this im ersten Beispiel auf die globale Variable in der fn-Funktion verweist, sodass this.count äquivalent zu window.count (in der Browserumgebung) ist und natürlich keinen Einfluss auf die Anzahl von hat Die Fn-Funktion hat Auswirkungen.
Zu beachten ist, dass die obige Situation nur im nicht strengen Modus (strenger Modus) auftreten kann. Im strikten Modus ist dies standardmäßig an undefiniert gebunden. Um eine Kontamination globaler Variablen zu vermeiden.
2.2 Implizite verbindliche Regeln
Wenn die Funktion mit einem Objekt als Kontext aufgerufen wird, ändert sich die Bindung dieses Objekts. Dies wird an das Objekt gebunden, das diese Funktion aufruft, siehe folgenden Code:
var obj = { a:1, fn:function(){ console.log(this.a); } } obj.fn(); //1
Auch wenn sich die Funktionsdeklaration nicht im Objekt befindet, ändert sich dieser Zeiger dennoch
function fn(){ console.log(this.a); } var obj = { a:1, fn:fn } obj.fn(); //1
Es ist ersichtlich, dass die Bindung nicht mit dem Speicherort der Funktionsdefinition zusammenhängt, sondern mit dem Aufrufer und der aufrufenden Methode.
Im Rahmen der impliziten Bindungsregeln gibt es einige Besonderheiten, auf die geachtet werden muss.
2.2.1 Mehrschichtiges Objekt ruft diesen Zeiger auf
function fn(){ console.log(this.a); } var obj = { a:1, obj2:obj2 } var obj2 = { a:2, obj3:obj3 } var obj3 = { a:3, fn:fn } obj.obj2.obj3.fn(); //3
Bei mehrstufigen Objektreferenzen zeigt dies auf das Objekt der aufgerufenen Funktion.
2.2.2 Implizite Zuordnung kann verloren gehen
Sehen Sie sich den Code unten an
function fn(){ console.log(this); } var obj = { fn:fn } var fun = obj.fn; fun(); //window
Obwohl fn auf obj.fun verweist, ist die Methode zum Aufrufen der Funktion immer noch unverändert, sodass sie immer noch an das Fenster gebunden ist.
Es gibt eine andere Situation, die jeder leicht übersehen kann: Wenn Parameter übergeben werden, wird tatsächlich eine implizite Zuweisung durchgeführt.
function fn(){ console.log(this); } function doFn(fn){ fn(); } var obj = { fn:fn } doFn(obj.fn); //window
Die implizite Bindung hierfür ist keine sehr empfehlenswerte Methode, da sie sehr wahrscheinlich verloren geht. Wenn im Unternehmen Anforderungen für die Bindung bestehen, wird die Verwendung einer expliziten Bindung empfohlen.
2.3 Explizite verbindliche Regeln
Explizite Bindung verwendet die Apply- und Call-Methoden des Funktionsprototyps, um dies zu binden. Die Verwendung besteht darin, das Objekt, das Sie binden möchten, als ersten Parameter zu übergeben.
function fn(){ console.log(this); } var obj = {}; fn.call(obj); //{}
Manchmal möchten Sie das This einer Funktion an ein Objekt binden, müssen es aber nicht sofort aufrufen. In diesem Fall ist dies nicht direkt mit call oder apply möglich.
function fn(){ console.log(this); } function bind(fn){ fn(); } var obj = { fn:fn } bind.call(obj,fn); //window
Das obige Beispiel scheint zu funktionieren, aber tatsächlich ist diese Bindungsfunktion an das Objekt obj gebunden, aber fn wird immer noch ohne Änderungen aufgerufen, sodass fn immer noch die Standardbindungsmethode ist.
function fn(){ console.log(this); } function bind(fn,obj){ return function(){ fn.apply(obj,arguments); } } var obj = { fn:fn } var fun = bind(fn,obj); fun(); //obj
这样调用,就可以将灵活多变的 this ,牢牢的控制住了,因为 fn 的调用方式为 apply 调用。所以,this 就被绑定在传入的 obj 对象上,在 ES5 当中,函数的原型方法上多了一个 bind。效果与上面的函数基本一致,具体用法限于篇幅就不多说了。
2.4 new 绑定
new 是一个被很多人误解的一个关键字,但实际上 javascript 的 new 与传统面向对象的语言完全不同。
个人把 new 理解为一种特殊的函数调用,当使用 new 关键字来调用函数的时候,会执行下面操作,
- 创建一个全新的对象
- 将空对象的 __proto__ 指向构造函数的 prototype
- 将新对象的 this 绑定到调用的函数上
- 如果函数返回值为基本类型或者为 this又或者不返回任何值,那么将会返回这个创建的新对象,如果返回了一个对象,那么则会返回这个对象,而不会返回创建的新对象。
function fn(a){ this.a = a; } fn.prototype.hi = function(){ console.log('hi') } var obj = new fn(2); console.log(obj); function fn(a){ this.a = a; return {}; } var obj = new fn(2); console.log(obj); //{}
2.5 特殊的传参
null 和 undefined 也是可以作为 this 的绑定对象的,但是实际上应用的是默认的绑定。
但是这种传参的实际效用是什么呢?
常见的用法是将一个数组展开,作为参数传入参数。比如
function fn(a,b){ console.log('a:',a,'b:',b); } fn.apply(null,[1,2]); // a: 1 b: 2
但是这种用法会有一个坑,那就是如果函数存在了 this ,那么就会应用默认的绑定规则,将 this 绑定在全局对象上,发生于预期不一致的情况。为了代码更加稳健,可以使创建一个比空对象更空的对象。
var obj = Object.create(null); console.log(obj.__proto__); //undefined var obj2 = {} console.log(obj2.__proto__); //Object {}
Object原型上有一个 create 方法,这个方法会创建一个对象,然后将对象的原型指向传入的参数,所以传入 null 的话,产生一个没有 prototype 的对象,所以会比空对象更加"空"。
所以传入这个对象,会比传入 null 更加安全。
var obj = Object.create(null); fn.apply(obj,[1,2]);
2.6 根据作用域来决定 this 的绑定
在 ES6 当中,出现了一个新的函数类型,箭头函数。
如果使用箭头函数,那么就不会使用上面提到的四种 this 绑定方式,而是根据作用域来决定
比较常见的是用于事件函数和定时器的情况。
下面是比较常见的传统 this 写法
function fn(){ var _this = this; setTimeout(function(){ console.log(_this.a); },100) } var obj = { a:2 } fn.call(obj); //2
如果使用箭头函数则可以这么写
function fn(){ setTimeout(()=>{ //this 来源于 fn 函数的作用域 console.log(this.a); },100) } var obj = { a:2 } fn.call(obj); //2
2.7 事件函数当中 this 的绑定机制
如果是在事件函数当中,this 的绑定是指向触发事件的 DOM 元素的,
$('body')[0].addEventListener('click',function(){ console.log(this); },false);
点击 body 元素之后,控制台则会显示 body 元素
3. 小结
如果想判断一个函数的 this 绑定在哪里,首先是找到函数的调用位置,之后是按照规则来判断。
- 如果函数调用时没有任何修饰条件,那么在严格模式下则会绑定到 undefined ,非严格模式下会绑定到全局。
- 如果是用对象做上下文,来对函数进行调用,那么则会绑定到调用的这个对象上。
- 如果是用 call 或者 apply 方法来进行调用的,则会绑定到第一个传入参数上。
- 如果是使用 new 关键字来调用函数的,则会绑定到新创建的那个对象上.
- 如果是在事件函数内,则会绑定到触发事件的那个DOM元素上。
以上就是关于Javascript中神奇的this的相关介绍,希望对大家的学习有所帮助。

Es ist für Entwickler wichtig, zu verstehen, wie die JavaScript -Engine intern funktioniert, da sie effizientere Code schreibt und Leistungs Engpässe und Optimierungsstrategien verstehen kann. 1) Der Workflow der Engine umfasst drei Phasen: Parsen, Kompilieren und Ausführung; 2) Während des Ausführungsprozesses führt die Engine dynamische Optimierung durch, wie z. B. Inline -Cache und versteckte Klassen. 3) Zu Best Practices gehören die Vermeidung globaler Variablen, die Optimierung von Schleifen, die Verwendung von const und lass und die Vermeidung übermäßiger Verwendung von Schließungen.

Python eignet sich besser für Anfänger mit einer reibungslosen Lernkurve und einer kurzen Syntax. JavaScript ist für die Front-End-Entwicklung mit einer steilen Lernkurve und einer flexiblen Syntax geeignet. 1. Python-Syntax ist intuitiv und für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet. 2. JavaScript ist flexibel und in Front-End- und serverseitiger Programmierung weit verbreitet.

Python und JavaScript haben ihre eigenen Vor- und Nachteile in Bezug auf Gemeinschaft, Bibliotheken und Ressourcen. 1) Die Python-Community ist freundlich und für Anfänger geeignet, aber die Front-End-Entwicklungsressourcen sind nicht so reich wie JavaScript. 2) Python ist leistungsstark in Bibliotheken für Datenwissenschaft und maschinelles Lernen, während JavaScript in Bibliotheken und Front-End-Entwicklungsbibliotheken und Frameworks besser ist. 3) Beide haben reichhaltige Lernressourcen, aber Python eignet sich zum Beginn der offiziellen Dokumente, während JavaScript mit Mdnwebdocs besser ist. Die Wahl sollte auf Projektbedürfnissen und persönlichen Interessen beruhen.

Die Verschiebung von C/C zu JavaScript erfordert die Anpassung an dynamische Typisierung, Müllsammlung und asynchrone Programmierung. 1) C/C ist eine statisch typisierte Sprache, die eine manuelle Speicherverwaltung erfordert, während JavaScript dynamisch eingegeben und die Müllsammlung automatisch verarbeitet wird. 2) C/C muss in den Maschinencode kompiliert werden, während JavaScript eine interpretierte Sprache ist. 3) JavaScript führt Konzepte wie Verschlüsse, Prototypketten und Versprechen ein, die die Flexibilität und asynchrone Programmierfunktionen verbessern.

Unterschiedliche JavaScript -Motoren haben unterschiedliche Auswirkungen beim Analysieren und Ausführen von JavaScript -Code, da sich die Implementierungsprinzipien und Optimierungsstrategien jeder Engine unterscheiden. 1. Lexikalanalyse: Quellcode in die lexikalische Einheit umwandeln. 2. Grammatikanalyse: Erzeugen Sie einen abstrakten Syntaxbaum. 3. Optimierung und Kompilierung: Generieren Sie den Maschinencode über den JIT -Compiler. 4. Führen Sie aus: Führen Sie den Maschinencode aus. V8 Engine optimiert durch sofortige Kompilierung und versteckte Klasse.

Zu den Anwendungen von JavaScript in der realen Welt gehören die serverseitige Programmierung, die Entwicklung mobiler Anwendungen und das Internet der Dinge. Die serverseitige Programmierung wird über node.js realisiert, die für die hohe gleichzeitige Anfrageverarbeitung geeignet sind. 2. Die Entwicklung der mobilen Anwendungen erfolgt durch reaktnative und unterstützt die plattformübergreifende Bereitstellung. 3.. Wird für die Steuerung von IoT-Geräten über die Johnny-Five-Bibliothek verwendet, geeignet für Hardware-Interaktion.

Ich habe eine funktionale SaaS-Anwendung mit mehreren Mandanten (eine EdTech-App) mit Ihrem täglichen Tech-Tool erstellt und Sie können dasselbe tun. Was ist eine SaaS-Anwendung mit mehreren Mietern? Mit Multi-Tenant-SaaS-Anwendungen können Sie mehrere Kunden aus einem Sing bedienen

Dieser Artikel zeigt die Frontend -Integration mit einem Backend, das durch die Genehmigung gesichert ist und eine funktionale edtech SaaS -Anwendung unter Verwendung von Next.js. erstellt. Die Frontend erfasst Benutzerberechtigungen zur Steuerung der UI-Sichtbarkeit und stellt sicher, dass API-Anfragen die Rollenbasis einhalten


Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

PHPStorm Mac-Version
Das neueste (2018.2.1) professionelle, integrierte PHP-Entwicklungstool

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

EditPlus chinesische Crack-Version
Geringe Größe, Syntaxhervorhebung, unterstützt keine Code-Eingabeaufforderungsfunktion

SublimeText3 Englische Version
Empfohlen: Win-Version, unterstützt Code-Eingabeaufforderungen!

SAP NetWeaver Server-Adapter für Eclipse
Integrieren Sie Eclipse mit dem SAP NetWeaver-Anwendungsserver.