“this”如何影响方法的方法?

时间:2013-10-03 17:03:49

标签: javascript

我正在研究udacity的课程并遇到问题。

https://www.udacity.com/course/viewer#!/c-cs255/l-49464373/e-73862317/m-73162952

function xhrGet(reqUri,callback) {
    var xhr = new XMLHttpRequest();

    xhr.open("GET", reqUri, true);
    xhr.onload = callback;

    xhr.send();
}

var TILEDMapClass = Class.extend({

    // Boolean flag we set once our map atlas
    // has finished loading.
    fullyLoaded: false,

    //-----------------------------------------
    // Load the json file at the url 'map' into
    // memory. This is similar to the requests
    // we've done in the past using
    // XMLHttpRequests.
    load: function (map) {

        // Perform an XMLHttpRequest to grab the
        // JSON file at url 'map'. We've provided
        // the xhrGet function from the optional
        // unit for you to use if you want.
        //
        // Once the XMLHttpRequest loads, set the
        // 'fullyLoaded' flag to true.
        //
        // YOUR CODE HERE
        xhrGet(map, function(){
            this.fullyLoaded = true;
        });
    }

});

// We define a single global instance of our
// map for the rest of our game code to access.
var gMap = new TILEDMapClass();

该链接表示它使用gMap.load.apply(gMap, [jsonURL]); http://forums.udacity.com/questions/100058023/scope-of-this#cs255

但我认为尽管使用被调用的方法这一事实。(负载将属于gMap)

但是因为

xhr.onload = function(){
                this.fullyLoaded = true;
            }

是属于xhr对象的方法,

并且this位于匿名函数

this应该引用xhr而不是gMap。

为什么this引用gMap?

3 个答案:

答案 0 :(得分:2)

这个在闭包中很有趣。您必须记住,this关键字通常会引用方法的所有者。通常是调用者(全局函数的窗口),但是当一个方法被调用为对象的属性时,这将引用该对象本身。

请参阅:“如果函数作为父项的属性调用,则指的是函数代码中的父对象。” Understanding this

直接来自Understanding this的规则:

  • 默认情况下,这是指全局对象。
  • 当一个函数作为父对象的属性调用时,这个 指的是该函数内的父对象。
  • 当使用new运算符调用函数时,这指的是 该函数内新创建的对象。
  • 当使用call或apply调用函数时,这指的是 传递给call或apply的第一个参数。如果第一个参数为null 或者不是对象,这是指全局对象。

答案 1 :(得分:1)

this并不一定意味着它被调用的函数或对象,如果你习惯使用jQuery并且对此感到困惑,jQuery方法实际上设置了this通过调用将this设置为调用者的这两个函数之一来方便函数:

call(object, arg0, arg1...);
apply(object, args[]);

基本上,除非函数通过调用上述函数之一设置this,否则它将被设置为某个外部函数/对象或window

答案 2 :(得分:1)

javascript函数中的“this”与函数所属的对象无关,但它执行的对象

与Java形成对比,那些是相同的,因为一个方法确实是一个对象的一部分,没有一个方法就不存在(不考虑静态)。

例如:

var blah = {
  test: function () {
    console.log('test');
  }
};
var f = blah.test;
var bleh = {
  test: blah.test
}

如果我然后进行这三个函数调用中的每一个,那么每个调用中指向的是什么?

blah.test();  // this points to blah
f();          // this is null (or undefined, not sure which)
bleh.test();  // this is bleh

我也可以使用Function.call在任何对象的上下文中调用函数对象:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

f.call(window);  // this is window

在使用回调时理解“this”很困难,因为回调函数通常由其他库(例如jquery)调用,并且它们的API可能会或可能不会保证“this”所指的内容。你可以做什么作为解决办法:

someAsyncFunction(function () {
  bleh.test();
});

这将确保使用可预测的“this”引用调用您关心的函数。