我希望找到一个“this”关键字的明确解释,以及如何正确使用它。

它的行为似乎很奇怪,我不完全明白为什么。

这是如何工作的,何时使用?


当前回答

丹尼尔,太棒了!在事件处理程序的情况下,这里有几个单词,以及这个执行上下文指针的良好列表。

换句话说,JavaScript中的这一点指向运行当前函数的对象(或其执行上下文),并且它始终是只读的,无论如何都不能设置它(这样的尝试将以“赋值中的左侧无效”消息结束)。

对于事件处理程序:内联事件处理程序,例如<elementonclick=“foo”>,会覆盖之前附加的任何其他处理程序,因此要小心,最好不要进行内联事件委派。感谢Zara Alaverdyan,他通过一场不同意见的辩论激发了我的灵感:)

el.onclick=foo;//在foo-obj中el.onclick=函数(){this.style.color=“#fff”;}//objel.onclick=function(){doSomething();}//在doSometing中-窗el.addEventListener('click',foo,false)//在foo-obj中el.attachEvent('包含,函数(){//this}')//窗口,所有符合IE:)<button onclick=“this.style.color='#fff';”>//obj<button onclick=“foo”>//在foo窗口中,但您可以<buttononclick=“foo(this)”>

其他回答

这能帮什么忙?(javascript中“this”的大部分混淆是因为它通常不链接到您的对象,而是链接到当前的执行范围——这可能不是它的确切工作方式,但对我来说总是这样——请参阅文章以获得完整的解释)

关于这一点,最详细和最全面的文章可能是以下内容:

JavaScript中“this”关键字的温和解释

这背后的想法是理解函数调用类型对设置该值具有重要意义。


当难以识别时,不要问自己:

这是从哪里来的?

但一定要问问自己:

如何调用函数?

对于箭头函数(上下文透明的特殊情况),问问自己:

在定义箭头函数的地方有什么值?

在处理这个问题时,这种心态是正确的,会让你免于头痛。

要正确理解“这”,就必须理解上下文和范围以及它们之间的区别。

作用域:在javascript中,作用域与变量的可见性有关,作用域通过使用函数实现。(阅读有关范围的更多信息)

上下文:上下文与对象相关。它指函数所属的对象。当您使用JavaScript“this”关键字时,它指的是函数所属的对象。例如,在函数内部,当你说:“this.accoutNumber”时,你指的是属性“accoutNumber”,该属性属于该函数所属的对象。

如果对象“myObj”有一个名为“getMyName”的方法,当JavaScript关键字“this”在“getMyName”中使用时,它将引用“myObj”。如果函数“getMyName”是在全局范围内执行的,那么“this”是指窗口对象(严格模式除外)。

现在让我们看看一些示例:

    <script>
        console.log('What is this: '+this);
        console.log(this);
    </script>

在浏览器输出中运行abobve代码将:

根据窗口对象上下文中的输出,也可以看到窗口原型引用了对象。

现在让我们尝试函数内部:

    <script>
        function myFunc(){
            console.log('What is this: '+this);
            console.log(this);
        }
        myFunc();
    </script>

输出:

输出是相同的,因为我们将“this”变量记录在全局范围中,并将其记录在函数范围中,我们没有更改上下文。在这两种情况下,上下文都是相同的,与寡妇对象相关。

现在让我们创建自己的对象。在javascript中,可以通过多种方式创建对象。

 <script>
        var firstName = "Nora";
        var lastName = "Zaman";
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printNameGetContext:function(){
                console.log(firstName + " "+lastName);
                console.log(this.firstName +" "+this.lastName);
                return this;
            }
        }

      var context = myObj.printNameGetContext();
      console.log(context);
    </script>

输出:

因此,从上面的示例中,我们发现“this”关键字引用的是与myObj相关的新上下文,而myObject也具有到Object的原型链。

让我们再举一个例子:

<body>
    <button class="btn">Click Me</button>
    <script>
        function printMe(){
            //Terminal2: this function declared inside window context so this function belongs to the window object.
            console.log(this);
        }
        document.querySelector('.btn').addEventListener('click', function(){
            //Terminal1: button context, this callback function belongs to DOM element 
            console.log(this);
            printMe();
        })
    </script>
</body>

输出:有道理吧?(阅读评论)

如果您无法理解上面的示例,让我们尝试使用自己的回调;

<script>
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printName:function(callback1, callback2){
                //Attaching callback1 with this myObj context
                this.callback1 = callback1;
                this.callback1(this.firstName +" "+this.lastName)
                //We did not attached callback2 with myObj so, it's reamin with window context by default
                callback2();
                /*
                 //test bellow codes
                 this.callback2 = callback2;
                 this.callback2();
                */
            }
        }
        var callback2 = function (){
            console.log(this);
        }
        myObj.printName(function(data){
            console.log(data);
            console.log(this);
        }, callback2);
    </script>

输出:

现在,让我们了解范围、自我、IIFE和THIS的行为

       var color = 'red'; // property of window
       var obj = {
           color:'blue', // property of window
           printColor: function(){ // property of obj, attached with obj
               var self = this;
               console.log('In printColor -- this.color: '+this.color);
               console.log('In printColor -- self.color: '+self.color);
               (function(){ // decleard inside of printColor but not property of object, it will executed on window context.
                    console.log(this)
                    console.log('In IIFE -- this.color: '+this.color);
                    console.log('In IIFE -- self.color: '+self.color); 
               })();

               function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
                    console.log('nested fun -- this.color: '+this.color);
                    console.log('nested fun -- self.color: '+self.color);
               }

               nestedFunc(); // executed on window context
               return nestedFunc;
           }
       };

       obj.printColor()(); // returned function executed on window context
   </script> 

输出非常棒,对吧?

关于此关键字的一些信息

让我们将此关键字记录到全局范围内的控制台中,无需任何代码

console.log(this)

在客户端/浏览器中,此关键字是一个全局对象,它是窗口

console.log(this === window) // true

and

在Server/Node/Javascript运行时中,此关键字也是一个全局对象,即module.exports

console.log(this === module.exports) // true
console.log(this === exports) // true

请记住,导出只是对module.exports的引用

javascript中的每个执行上下文都有一个this参数,该参数由以下参数设置:

如何调用函数(包括作为对象方法、调用和应用的使用、new的使用)绑定的使用箭头函数的词汇(它们采用外部执行上下文的this)代码是严格模式还是非严格模式是否使用eval调用代码

可以使用func.all、func.apply或func.bind设置此值。

默认情况下,当在DOM元素上引发事件后调用监听器时,函数的这个值就是DOM元素,这让大多数初学者感到困惑。

jQuery使用jQuery.proxy进行更改变得很简单。