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)
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"}
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 exceeded
var obj = { then: function (resolve, reject) { setTimeout(function () { resolve(1000); }, 1000) } } Promise.resolve(obj).then(function (data) { console.log(data);// 延迟1秒左右输出 1000 })
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 })
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); // 2
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!