javascript范围说明

时间:2014-01-24 04:18:04

标签: javascript scope

简单的问题。为什么我们设置that = this?如果我们不这样做,我们处于全球范围......但为什么呢?

var myObj = {

    specialFunction: function () {

    },

    anotherSpecialFunction: function () {

    },

    getAsyncData: function (cb) {
        cb();
    },

    render: function () {
        var that = this;
        this.getAsyncData(function () {
            // this now refers to global scope....why?
            that.specialFunction();
            that.anotherSpecialFunction();
        });
    }
};

myObj.render();

3 个答案:

答案 0 :(得分:2)

that = this不会改变范围。调用匿名函数的方式始终以this为全局对象*,因为that's exactly what the spec says should happen.使用that = this只是一种解决方法。

您可以this始终使用Function.call指向myObj

var myObj = {

    specialFunction: function () {

    },

    getAsyncData: function (cb) {
        cb.apply(this);
    },

    render: function () {
        this.getAsyncData(function () {
            this.specialFunction();
        });
    }
};

和/或使用Function.bind

var myObj = {

    specialFunction: function () {

    },

    getAsyncData: function (cb) {
        cb();
    },

    render: function () {
        function callback() {
            this.specialFunction();
        }

        this.getAsyncData(callback.bind(this));
    }
};

*除非您处于严格模式,否则thisundefined

答案 1 :(得分:0)

JavaScript中的

编辑:“此”上下文取决于您的函数的调用方式,例如:

 function helloWorld()
 {
    console.log(this);
 }
  

这里有两种调用此函数的方法:

     

新的helloWorld(); 请注意,如果你在此调用你的函数   方式,这个上下文将是函数+的上下文   原型,所以你的控制台将显示:helloWorld {}

     

helloWorld(); 如果你在没有“新”的情况下调用你的函数,   “this”的上下文将是全局的(Window),因此您的控制台将显示   这个:关于:家的窗口

     

好的,有了这个小解释,我会试着解释一下你为什么这么做   有时候会使用self / that ......

想象一下,您想在this.name函数中使用this.hello。就像我之前说的那样,“this”的上下文取决于你的函数的调用方式,所以如果你想确保this.hello函数中的this.name引用this.name,建议你使用self / that来避免发生的事情

function helloWorld(){
             var self = this;//or that = this
             this.name = "YourName" 
             this.hello = function(){
                 console.log(this); //the context of "this" here will be: "hello {}" 
                 return this.name; //undefined, because you don't have name attribute inside hello function
             }
             new this.hello(); //note how hello is called here... 

}

var test = new helloWorld(); 

这里有关于上下文x范围的一个很好的解释: http://ryanmorr.com/understanding-scope-and-context-in-javascript/

答案 2 :(得分:0)

在JavaScript中查看this关键字及其工作原理。我相信我们都遇到过这个问题:

 $("myLink").on("click", function() {
    console.log(this); //points to myLink (as expected)
    $.ajax({
        //ajax set up
        success: function() {
            console.log(this); //points to the global object. Huh?
        }
    });
});

这是一个在调用函数时自动为您设置的变量。它给出的值取决于函数的调用方式。在JavaScript中,我们有几种主要的调用函数的方法。我今天不会谈论它们,但只是大多数人使用它们的三种方式;当一个函数被调用为一个方法,或者它自己,或作为一个事件处理程序。根据函数的调用方式,设置方式不同:

function foo() {
    console.log(this); //global object
};

myapp = {};
myapp.foo = function() {
    console.log(this); //points to myapp object
}

var link = document.getElementById("myId");
link.addEventListener("click", function() {
    console.log(this); //points to link
}, false);

执行$(“myLink”)。on(“click”,function(){})意味着单击该元素时会触发该函数。但是此函数被绑定为事件处理程序,因此将其设置为对DOM元素myLink的引用。您在Ajax请求中定义的成功方法只是一个常规函数,因此当它被调用时,它被设置为全局对象,就像任何不是事件处理程序或对象方法的函数一样。

$("myLink").on("click", function() {
    console.log(this); //points to myLink (as expected)
    var _this = this;  //store reference
    $.ajax({
        //ajax set up
        success: function() {
            console.log(this); //points to the global object. Huh?
            console.log(_this); //better!
        }
    });
});

来源:http://tinyurl.com/melbl92