Inhalt
Vorwort + Gedankenfragen
Ich erinnere mich, dass ich bei der Suche nach einem Praktikum immer einen Satz in meinen Lebenslauf eingefügt habe – mit JS vertraut, wie diesen, anrufen, bewerben usw.
(kostenlose Lernempfehlung: Javascript-Video-Tutorial)
Jedes Mal, wenn ich meinen Lebenslauf einreiche, werde ich die folgenden Schritte durchgehen
Die folgenden Fragen sind beliebte Fragen, die ich im Internet gesucht habe. Wenn die Experten sie leicht beantworten können. Wenn Sie eine haben Klare Idee, ihr könnt ihr genauso gut einen Daumen hoch geben (schließlich verbraucht es eine Menge Gehirnzellen). Es wäre sogar noch besser, wenn ihr mir in den Kommentaren ein paar Hinweise geben könntet! ! !
Füllen Sie die Lücken aus:
[ ]
wird eine neue Funktion erstellt, die mit der aufgerufenen Funktion übereinstimmt aufgerufen, dieser Wert zeigt auf den ersten Parameter. 【 】
函数会创建一个新函数,新函数与被调函数具有相同的函数体,当目标函数被调用时 this 值指向第一个参数。问答题:
代码分析题:
var name = 'window'var person1 = { name: 'person1', show1: function () { console.log(this.name) }, show2: () => console.log(this.name), show3: function () { return function () { console.log(this.name) } }, show4: function () { return () => console.log(this.name) }}var person2 = { name: 'person2' }person1.show1()person1.show1.call(person2)person1.show2()person1.show2.call(person2)person1.show3()()person1.show3().call(person2)person1.show3.call(person2)()person1.show4()()person1.show4().call(person2)person1.show4.call(person2)()
一、this的指向
百度、谷歌上输入“this的指向”关键字,大几千条文章肯定是有的,总不至于为了全方面、无死角的掌握它就要将所有的文章都看一遍吧?所以不如梳理出一个稳固的框架,顺着我们的思路来填充它。
执行环境
动态绑定的,而非函数被声明时的环境;被调用的方式
;1、作为对象的方法调用
当函数作为对象的方法被调用时,this指向该对象
var obj = { a: 'yuguang', getName: function(){ console.log(this === obj); console.log(this.a); }};obj.getName(); // true yuguang
2、作为普通函数调用
当函数不作为对象的属性被调用,而是以普通函数的方式,this总是指向全局对象(在浏览器中,通常是Window对象)
window.name = 'yuguang';var getName = function(){ console.log(this.name);};getName(); // yuguang
或者下面这段迷惑性的代码:
window.name = '老王'var obj = { name: 'yuguang', getName: function(){ console.log(this.name); }};var getNew = obj.getName;getNew(); // 老王
而在ES5的严格模式下,this被规定为不会指向全局对象,而是undefined
3、构造器调用
除了一些内置函数,大部分Js中的函数都可以成为构造器,它们与普通函数没什么不同
构造器和普通函数的区别在于被调用的方式
Frage und Antwort:
Bitte sprechen Sie über die Arten von Zeigerfunktionen, die diesen Zeiger innerhalb einer Funktion ändern, und was sind ihre Unterschiede? In welche Arten von Richtungen lässt sich das unterteilen?
Fragen zur Code-Analyse:
var MyClass = function(){ this.name = 'yuguang';}var obj = new MyClass();obj.name; // yuguang
1. Der Sinn davon
🎜🎜Geben Sie das Schlüsselwort „Punkt davon“ bei Baidu und Google ein, aber es ist nicht allumfassend. , Um es ohne blinde Flecken zu meistern, müssen Sie alle Artikel lesen, oder? Deshalb ist es besser, einen soliden Rahmen zu schaffen und ihn nach unseren Vorstellungen auszufüllen. 🎜🎜Mind Map🎜🎜🎜 🎜Die Wesentlicher Teil dieses Abschnitts: 🎜🎜🎜Dies zeigt immer auf ein Objekt (im nicht strikten Modus), und das spezifische Objekt, auf das gezeigt wird, wird zur Laufzeit dynamisch an dieAusführungsumgebung
der Funktion gebunden, nicht an die Funktion Die Umgebung, wenn sie deklariert wird; 🎜🎜Mit Ausnahme der ungewöhnlichen Situationen mit und eval kann dieser Zeiger in tatsächlichen Anwendungen grob in vier Typen unterteilt werden: 🎜🎜als Methodenaufruf eines Objekts; 🎜🎜als gewöhnlicher Funktionsaufruf; 🎜🎜 Konstruktoraufruf; 🎜🎜aufrufen oder anwenden 🎜🎜In einer Pfeilfunktion zeigt dies im oberen Bereich der Funktion an; wird aufgerufen;🎜🎜A,call(B) => Es kann verstanden werden, dass Methode A im Rahmen von B aufgerufen wird;🎜🎜🎜Analyse🎜🎜🎜1 🎜🎜Wenn die Funktion ein Objekt ist. Wenn eine Methode aufgerufen wird, <code>zeigt dies auf das Objekt
🎜var MyClass = function () { this.name = 1; return { name: 2 }}var myClass = new MyClass(); console.log('myClass:', myClass); // { name: 2}
var obj1 = { name: 1, getName: function (num = '') { return this.name + num; }};var obj2 = { name: 2,};// 可以理解成在 obj2的作用域下调用了 obj1.getName()函数console.log(obj1.getName()); // 1console.log(obj1.getName.call(obj2, 2)); // 2 + 2 = 4console.log(obj1.getName.apply(obj2, [2])); // 2 + 2 = 4
this.val = 2;var obj = { val: 1, getVal: () => { console.log(this.val); }}obj.getVal(); // 2
undefiniert
🎜🎜🎜3. Konstruktoraufruf🎜🎜🎜Mit Ausnahme einiger integrierter Funktionen können die meisten Funktionen in Js zu Konstruktoren werden. Sie unterscheiden sich nicht von gewöhnlichen Funktionen🎜🎜🎜Konstruktoren🎜und🎜gewöhnlich Der Unterschied zwischen Funktionen 🎜 liegt in der Art und Weise, wie aufgerufen wird
: 🎜 Wenn der neue Operator eine Funktion aufruft, gibt er immer ein Objekt zurück, und dieses zeigt normalerweise auf dieses Objekt 🎜var obj = { name: '1', getName: function (params) { console.log(this.name) }};obj.getName();var getName2 = obj.getName;getName2();
var getDomById = function (id) { return document.getElementById(id);};getDomById('p1') //dom节点
var getDomById = document.getElementByIdgetDomById('p1') // Uncaught TypeError: Illegal invocation(非法调用)
因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:
this.val = 2;var obj = { val: 1, getVal: () => { console.log(this.val); }}obj.getVal(); // 2
常见的坑
就像标题一样,有的时候this
会指向undefined
情况一
var obj = { name: '1', getName: function (params) { console.log(this.name) }};obj.getName();var getName2 = obj.getName;getName2();
这个时候,getName2()
作为普通函数被调用时,this指向全局对象——window。
情况二
当我们希望自己封装Dom方法,来精简代码时:
var getDomById = function (id) { return document.getElementById(id);};getDomById('p1') //dom节点
那么我们看看这么写行不行?
var getDomById = document.getElementByIdgetDomById('p1') // Uncaught TypeError: Illegal invocation(非法调用)
这是因为:
document
对象的方法时,方法内的this指向document
。getId
应用document
内的方法,再以普通函数的方式调用,函数内容的this
就指向了全局对象。利用call和apply修正情况二
document.getElementById = (function (func) { return function(){ return func.call(document, ...arguments) }})(document.getElementById) // 利用立即执行函数将document保存在作用域中
二、call和apply
不要因为它的“强大”而对它产生抗拒,了解并熟悉它是我们必须要做的,共勉!
先来看区别,是因为它们几乎没有区别,下文代码实例call和apply都可以轻易的切换。
当它们被设计出来时要做到的事情一摸一样,唯一的区别就在于传参的格式不一样
因为在所有(非箭头)函数中都可以通过arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,它本身就是一个类数组,我们apply在实际使用中更常见一些。
call是包装在apply上面的语法糖,如果我们明确的知道参数数量,并且希望展示它们,可以使用call。
当使用call或者apply的时候,如果我们传入的第一个参数为null,函数体内的this会默认指向宿主对象,在浏览器中则是window
。
借用其他对象的方法
我们可以直接传null来代替任意对象
Math.max.apply(null, [1, 2, 3, 4, 5])
使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数——来时MDN
实现继承
;this
;1.调用构造函数来实现继承
通过“借用”的方式来达到继承的效果:
function Product(name, price) { this.name = name; this.price = price;}function Food(name, price) { Product.call(this, name, price); // this.category = food;}var hotDog = new Food('hotDog', 20);
2.调用函数并且指定上下文的 this
此时this被指向了obj
function showName() { console.log(this.id + ':' + this.name);};var obj = { id: 1, name: 'yuguang'};showName.call(obj)
3.使用call单纯的调用某个函数
Math.max.apply(null, [1,2,3,10,4,5]); // 10
三、模拟实现一个call
先来看一下call帮我们需要做什么?
var foo = { value: 1};function show() { console.log(this.value);};show.call(foo); //1
就像解方程,要在已知条件中寻找突破哦口:
call
使得this的指向变了,指向了foo;show
函数被执行了;this
+ 参数列表;第一版代码
上面提到的3点,仅仅完成了一点,且传入的参数
var foo = { value: 1};function show() { console.log(this.value);};Function.prototype.setCall = function (obj) { console.log(this); // 此时this指向show obj.func = this; // 将函数变成对象的内部属性 obj.func(obj.value); // 指定函数 delete obj.func // 删除函数,当做什么都没发生~}show.setCall(foo);
第二版代码
为了解决参数的问题,我们要能获取到参数,并且正确的传入:
var foo = { value: 1};function show(a, b) { console.log(this.value); console.log(a + b);};Function.prototype.setCall = function (obj) { obj.fn = this; // 将函数变成对象的内部属性 var args = []; for(let i = 1; i <p>此时,我们就可以做到,传入多个参数的情况下使用call了,但是如果你仅想用某个方法呢?</p><p><strong>第三版代码</strong></p><pre class="brush:php;toolbar:false">Function.prototype.setCall = function (obj) { var obj = obj || window; obj.fn = this; var args = []; for(var i = 1, len = arguments.length; i <p><strong>四、bind</strong></p><blockquote><p>bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用 —— MDN</p></blockquote><p>提到了<strong>call</strong>和<strong>apply</strong>,就绕不开<strong>bind</strong>。我们试着来模拟一个bind方法,以便加深我们的认识:</p><pre class="brush:php;toolbar:false">Function.prototype.bind = function (obj) { var _this = this; // 保存调用bind的函数 var obj = obj || window; // 确定被指向的this,如果obj为空,执行作用域的this就需要顶上喽 return function(){ return _this.apply(obj, arguments); // 修正this的指向 }};var obj = { name: 1, getName: function(){ console.log(this.name) }};var func = function(){ console.log(this.name);}.bind(obj);func(); // 1
这样看上去,返回一个原函数的拷贝,并拥有指定的 this 值,还是挺靠谱的哦~
写在最后
Der erste Teil des grundlegenden Teils der internen JavaScript-Kenntnisse. Zusammenfassend lässt sich sagen, dass diese Serie von Xian Yu sehr gefördert und inspiriert wurde. Diese Serie enthält etwa 15 Artikel, die wir alle am häufigsten interviewen, die aber bei der Arbeit oft ignoriert werden . .
Verwandte kostenlose Lernempfehlungen: Javascript(Video)
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterungen zu diesem Hinweis, damit Sie ihn verstehen, aufrufen und in einem Artikel anwenden können. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!