试图通过一个函数传递`this`

时间:2013-10-17 21:30:47

标签: javascript

我有一个本地化为main函数的函数,我想使用this来调用它,但它似乎不起作用。

我的代码有:

function option(room,slot){

    var div_id = document.getElementById(room);
    var opacity = window.getComputedStyle(div_id).opacity

    transition_opacity(div_id,opacity,0,function(){this.load});


    function load(){
    console.log('test'); //does not happen      
       }
}

当我使用this来呼叫function(){}时,我是否误解了load的使用或遗失了范围?

5 个答案:

答案 0 :(得分:2)

从您的代码中可以看出,this可以引用的对象并不明显。这取决于option的调用方式。但是,如果您在load函数内定义option函数,最好直接引用它。您必须将test的声明移到transition_opacity来电之上:

function option(room,slot){
    var div_id = document.getElementById(room);
    var opacity = window.getComputedStyle(div_id).opacity;

   function load() {
       console.log('test');
   }

   transition_opacity(div_id,opacity,0,load);
}

如您所见,我只是直接引用load。你可以创建另一个调用里面的load函数的函数(即function() { load(); } - 注意调用函数的括号)但这会给你没有好处,但只是添加另一个不需要的功能到堆栈。所以只需参考实际的功能本身。

有关this关键字的详细信息,请查看this question。掠夺者:它比你想象的要复杂得多。

答案 1 :(得分:1)

this的范围在此实例中丢失,可能指向该文档。您可以将其捕获到外部作用域中的变量,以使其按预期工作。

var context = this;
transition_opacity(div_id,opacity,0,function(){context.load();})

但上述方法无效。这是因为this的上下文中不存在加载。您需要定义加载函数:

context.load = function(){
   console.log('test');
}

答案 2 :(得分:1)

两个

首先,你的加载函数不是任何这个的成员/属性,你编码的方式。您的加载函数只是一个嵌套函数,存在于您的选项函数中,就像其他响应中隐含的一样。

在你的选项功能中,如果你想让'load'成为'this'的成员,你需要这样说,就像这样:

function option(){
    this.load = function(){};  // now load is actually a property of whatever this is
}

其次,你和另一张海报是正确的,当你的匿名函数被调用时,'this'不再是'this'。

无论何时调用函数,都会创建一个全新的“this”并存在于该函数的范围内。如果你只是调用这样的函数:

transition_opacity(args);

..然后在transition_opacity中,'this'只是指向窗口对象,或者可能是window.document。要使'this'引用除window或window.document之外的任何内容,您需要(实际上)执行以下操作之一:

myObject.transition_opacity(args);

transition_opacity.call(myObject, arg1, arg2, ..);

transition_opacity.apply(myObject, argArray);

var myObject = new transition_opacity(args);

在每种情况下,在transition_opacity中,'this'指的是myObject(或者,在最后一种情况下,它指的是正在创建并分配给myObject的新对象)。

这是一种做你想要做的事情的方法:

var MyNamespace = {

    option: function(room,slot){
        var div_id = document.getElementById(room);
        var opacity = window.getComputedStyle(div_id).opacity;

        var _this = this;
        transition_opacity(div_id,opacity,0,function(){
            // Careful! Inside here, 'this' is just window or window.document,
            // unless transition_opacity sets it to something using call or apply, 
            // in which case that 'this' is probably not the 'this' you want.
            // So carefully refer to the saved instance of 'this':
            _this.load();
        });
    },

    load: function(){
        console.log('test'); // now it should happen   
    }
}

.
.
MyNamespace.option(room, slot);  // inside option, 'this' is MyNamespace.

这是另一种方法:

function MyClass(){};
MyClass.prototype = {
   // all the same stuff that is in MyNamespace above..
};
.
.
var myObject = new MyClass();
myObject.option(room, slot);

清除泥土?

答案 3 :(得分:0)

只需使用

transition_opacity(div_id,opacity,0,load);

答案 4 :(得分:0)

您已将另一个函数中的“加载”定义为“函数声明”,因此现在只能在“选项”函数中以及在此函数中定义的其他函数中通过名称“加载”进行访问。无论'this'是什么,你都无法使用'this.load'来访问它。如果你想以“this.load”的形式访问'load'函数,你可以尝试这个例子来理解'this'kekewoard是如何工作的

// Function Declaration
function f1(callback){
  callback();
};
// Function Declaration
function f2(){
  // Function Expression
  this.load = function(){
    console.log("test");
  };
  f1(this.load);
};
var obj = new f2(); // test, this == obj, so obj.load() now exists
obj.load(); //test, this == obj
f2(); //test, this == window, so window.load() now exists
load(); //test, window is the global scope