Heim >Web-Frontend >js-Tutorial >Detaillierte Erklärung impliziter Aufrufe in Javascript
Der sogenannte implizite Aufruf bedeutet einfach, dass einige Methoden automatisch aufgerufen werden. Diese Methoden können extern wie Hooks geändert werden, wodurch das etablierte Verhalten geändert wird.
Nachfolgend werde ich einige implizite Aufrufe auflisten, die ich kürzlich gesehen habe. Die Beispiele sind genau das Richtige für das Hinzufügen von
var obj = { a: 1, toString: function () { console.log('toString') return '2' }, valueOf: function () { console.log('valueOf') return 3 } } console.log(obj == '2'); //依次输出 'valueOf' false console.log(String(obj));//依次输出 'toString' '2'
var obj = { a: 1, toString: function () { console.log('toString') return '2' }, valueOf: function () { console.log('valueOf') return {} //修改为对象 } } console.log(obj == '2'); //依次输出 'valueOf' 'toString' true console.log(Number(obj));//依次输出 'valueOf' 'toString' 2
Bei der Operation des Gleichheitsoperators ruft das Objekt zuerst valueOf auf. Wenn der zurückgegebene Wert ein Objekt ist, ruft es toSting auf, außer null, und verwendet dann den zurückgegebenen Wert zum Vergleich ist äquivalent zu 3 == '2' und gibt false aus. Das zweite Beispiel gibt ein Objekt zurück, weil valueOf ausgeführt wird, und dann wird toString ausgeführt. Schließlich entspricht es '2' == '2' und gibt true aus Bei den Number- und String-Methoden wird Number zuerst valueOf und dann toString aufgerufen. Das Gegenteil ist bei der String-Methode der Fall.
Zusätzlich zu den beiden oben genannten Beispielen gibt es die Datentypkonvertierung auch in verschiedenen anderen Operationen, z. B. bei numerischen Operationen. Wenn es sich um Referenztypen handelt, wird die Methode valueOf oder toString aufgerufen. Es wird diese beiden Methoden erben. Wir können diese beiden Methoden erneut überschreiben, um das Verhalten der Datentypkonvertierung zu beeinflussen
var eventObj = { a: 1, handleEvent: function (e) { console.log(this, e);//返回 eventObj 和 事件对象 alert(this.a) } } document.addEventListener('click', eventObj)Sie haben richtig gelesen, der zweite Parameter von addEventListener ist zusätzlich zur Funktion Es kann auch ein Objekt sein, nachdem das Ereignis ausgelöst wurde. Wenn die Methode ausgeführt wird, zeigt dies auf eventObj Sie können die gewünschten Daten binden an das eventObj-Objekt übergeben JSON-Objekt toJSON
var Obj = { a: 10, toJSON: function () { return { a: 1, b: function () { }, c: NaN, d: -Infinity, e: Infinity, f: /\d/, g: new Error(), h: new Date(), i: undefined, } } } console.log(JSON.stringify(Obj)); //{"a":1,"c":null,"d":null,"e":null,"f":{},"g":{},"h":"2018-02-09T19:29:13.828Z"}Wenn das von der JSON-Stringify-Methode übergebene Objekt eine toJSON-Methode hat, wird das von dieser Methode ausgeführte Objekt in das umgewandelt Das nach der Ausführung von toJSON zurückgegebene Objekt ist Folgendes zu beachten:
var Obj1 = { a: 10, toJSON: function () { console.log(this === Obj1);//true return this } } console.log(JSON.stringify(Obj1));//{"a":10}
var Obj2 = { a: 10, toJSON: function () { console.log(this === Obj2);//true return { a: this } } } console.log(JSON.stringify(Obj2));//报错 Maximum call stack size exceededWenn gemäß der obigen Aussage klar ist, dass der Fehler das ist, was wir erwartet haben, aber Wenn Sie dies direkt zurückgeben, wird überhaupt kein Fehler gemeldet. Sie können auch eine mutige Vermutung über den internen Vergleich zwischen dem von toJSON zurückgegebenen Objekt und dem Originalobjekt anstellen. Wenn sie gleich sind, verwenden Sie direkt das then
var obj = { then: function (resolve, reject) { setTimeout(function () { resolve(1000); }, 1000) } } Promise.resolve(obj).then(function (data) { console.log(data);// 延迟1秒左右输出 1000 })Versprechensobjekt Wenn die Methode Promise.resolve vorhanden ist, wird sie sofort ausgeführt, was dem Ersetzen der Methode Put entspricht Es wird in ein neues Promise umgewandelt. Zusätzlich zu Promise.resolve weist auch Promise.all dieses Verhalten auf
var timePromise = function (time) { return new Promise(function (resolve) { setTimeout(function () { resolve(time); }, time) }) } var timePromise1 = timePromise(1000); var timePromise2 = timePromise(2000); var timePromise3 = timePromise(3000); Array.prototype.then = function (resolve) { setTimeout(function () { resolve(4000); }, 4000) } Promise.all([timePromise1, timePromise2, timePromise3]).then(function (time) { console.log(time);// 等待4秒左右输出 4000 })Sie können sehen, welche Objektattribut-Accessoren erhalten und festlegen
var obj = { _age: 100, get age() { return this._age < 18 ? this._age : 18; }, set age(value) { this._age = value; console.log(`年龄设置为${value}岁`); } } obj.age = 1000; //年龄设置为1000岁 obj.age = 200; //年龄设置为200岁 console.log(obj.age);// 18 obj.age = 2; ////年龄设置为2岁 console.log(obj.age); // 2Unabhängig davon, welches Alter festgelegt ist, ist mein Alter 18 Jahre oder jünger. Beim Ausführen des Attributzugriffs wird tatsächlich die entsprechende Get-Set-Funktion des Objektattributs aufgerufen. Zusätzlich zur oben genannten Schreibmethode gibt es auch die folgende Schreibmethode >
Jetzt sind der Wert der Eingabe und der innerHTML-Wert der Attributwertspanne von obj.age miteinander verbunden
var input = document.createElement('input'); var span = document.createElement('span'); document.body.appendChild(input); document.body.appendChild(span); var obj = { _age:'' } var obj = Object.defineProperty(obj, 'age', { get: function () { return this._age; }, set: function (value) { this._age = value; input.value = value; span.innerHTML = value; } }); input.onkeyup = function (e) { if (e.keyCode === 37 || e.keyCode === 39) { return; } obj.age = this.value }
Iterator-Schnittstelle Symbol.iterator
Sie kann alles sehen Wenn Sie den Spread-Operator aufrufen oder eine for...of-Schleife zum Durchlaufen eines Objekts verwenden, wird die Traverser-Schnittstelle des Objekts aufgerufen, z. B. Array, String, Map, Set, TypedArray und einige arrayähnliche Objekte wie Argumente und NodeList Gewöhnliche Objekte verfügen nicht über diese Schnittstelle. Wenn Sie möchten, dass das Objekt den Spread-Operator oder die for...of-Schleife verwenden kann, können Sie diese Methode zum Objekt hinzufügen oder die Methode neu schreiben auf das ursprüngliche Objekt mit der Schnittstelle, um dessen Verhalten zu ändern.var arr = [ 1, 2 , 3]; arr[Symbol.iterator] = function () { const self = this; let index = 0; return { next () { if(index < self.length) { return { value: self[index] ** self[index++], done: false } } else { return { value: undefined, done: true } } } } } console.log([...arr, 4]);//返回 [1, 4, 27, 4] for(let value of arr) { console.log(value); //依次返回 1 4 27 }
Verwandte Empfehlungen:
php, wie eine Unterklasse implizit die Methode der übergeordneten Klasse aufruftDas obige ist der detaillierte Inhalt vonDetaillierte Erklärung impliziter Aufrufe in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!