使用调用来传递上下文

时间:2015-06-20 05:10:42

标签: javascript call

我正在尝试使用call传递Utilities对象的上下文,以便我可以在myTest函数中访问其成员(allData数组等)。

我收到错误:

  

ReferenceError:未定义allData

这告诉我上下文丢失了,我想我没有正确绑定上下文。我该怎么做?

var Utilities = {
    allData : [],
    storage : [],

    apiRequest : function () {
        this.allData = ["a","b","c"];
        var myTest = this.allData.map.call(this, function (i, el) {
            var url = 'testPHP.php/translate_tts?ie=utf-8&tl=zh-CN&q=' + i;
            return $.get(url, function (returned_data) {
                this.storage.push(returned_data);
            });
        });

        $.when.apply($, myTest).done(function () {
            log('done!');
            log(this.storage[i]);
        });

2 个答案:

答案 0 :(得分:2)

提醒

Javascript中只有功能级别上下文,而this只不过是一个局部变量。默认情况下,this设置为全局window对象:

function me () { return this; };
me() === window; // true

或调用函数的对象:

var o = {};
o.me = me;
o.me() === o; // true

了解这一点,请仔细阅读以下内容:

var me = o.me;
me === o.me; // true, not a copy
me() === o; // false
me() === window; // true

var p = {};
p.me = o.me;
p.me() === p; // true
o.me() === o; // true

如您所见,this在函数调用时自动设置。这是默认行为,但您也可以使用.call().apply()(一次性)自行完成:

me.call(o) === o; // true
me.apply(o) === o; // true
p.me.call(o) === o; // true
me() === window; // true

最近,.bind()(永久):

me = me.bind(o);
me() === o; // true
me() === window; // false

您的问题

我会使用.bind()

var Utilities = {
    allData : [],
    storage : [],

    apiRequest : function () {
        this.allData = ["a","b","c"];
        var myTest = this.allData.map(function (i, el) {
            var url = 'testPHP.php/translate_tts?ie=utf-8&tl=zh-CN&q=' + i;
            return $.get(url, function (returned_data) {
                this.storage.push(returned_data);
            }.bind(this));
        }.bind(this));

        $.when.apply($, myTest).done(function () {
            log('done!');
            // I've added a loop here
            var i, l = arguments.length;
            for (i = 0; i < l; i++) {
                log(this.storage[i]);
            }
        }.bind(this));

答案 1 :(得分:1)

上面的答案很棒。在这一点上要强调的一件事是:无论何时在初始化时绑定对象,它都将被绑定,并且不能再次使用其他上下文调用/应用。 IMO由您决定是使用call / apply在运行时)还是.bind(永久)。

从这里开始:

  

我正在尝试使用call来传递Utilities对象的上下文,这样我就可以在myTest函数中访问它的成员(allData数组等)。

var OtherTest = function() {
    this.dataStorage.push(["ok"]);
    console.log(arguments);
}

var Utilities = {
    dataStorage: [],
    allData: [],
    apiRequest: function() {
        this.allData = ["a","b","c"];

        OtherTest.apply(this,arguments);

    }
}


Utilities.apiRequest('hu','hu');
console.log(Utilities.dataStorage[0]);

由于this是对象的引用,因此可以在初始化后随时进行变更,以便于call / apply传递上下文在这种情况下,Utilities对象