javascript类问题

sim*_*man 0 javascript

检查此代码

    var _class=function()
    {
        this.Test=100;
        this.Callback=function(msg)
        {
            alert(msg+"\r\n"+this.Test);
        }
    }

    function run(call)
    {
        call("Hello world");
    }

    var obj=new _class();
    run(obj.Callback);
Run Code Online (Sandbox Code Playgroud)

我得到了结果:

    [Alert]
    Hello world
    undefined
Run Code Online (Sandbox Code Playgroud)

但是当我打电话给obj.Callback("你好世界")

我得到了预期

    [Alert]
    Hello world
    100
Run Code Online (Sandbox Code Playgroud)

为什么?

谢天谢地

Poi*_*nty 6

对象与"内部"定义的函数之间没有内在关系.的唯一确定的值的东西this在函数调用(称为"接收"对象)是其中函数被调用的方法.

  • object.func(),this并将被绑定的函数调用object.
  • 使用"call()"或"apply()"调用函数,this并由第一个参数确定.
  • 但是,如果在没有任何隐式对象上下文的情况下调用函数,就像在"回调"示例中那样,那么this就不会引用任何对象 - 它将引用window(或者无论全局上下文是什么).

诀窍在于,当你想要使用一个函数就好像它是一个对象上的"方法"时,即使函数引用已经从对象中拉出来,关系仍保持不变,你可以预先绑定this一对方式:

  1. 您可以将该函数包装在另一个函数中,以便明确保留this在闭包中.
  2. 您可以使用".bind()"来(基本上)执行相同的操作.

第一种方式看起来像这样:

run(function() { obj.Callback(); });
Run Code Online (Sandbox Code Playgroud)

第二种方式如下:

run(obj.Callback.bind(obj));
Run Code Online (Sandbox Code Playgroud)

在这方面,JavaScript与C#或Java等语言截然不同.在这些语言中,函数永远处于与其类(或其类的实例)的关系中.不是JavaScript; 实际上,它确实无关紧要,其中定义了一个函数.如果它是这样编写的,那么你的"_class"函数将是等效的:

function helloThere() { 
   alert(msg + "\r\n" + this.Test);
}

var _class = function() {
    this.Test = 100;
    this.Callback = helloThere;
};
Run Code Online (Sandbox Code Playgroud)

编辑 - @jamietre正确地注意到你的"_class"函数包含一些var声明或本地函数,那么肯定会有区别(虽然不是关于this调用"Callback"时的行为方式).

再次编辑 - 谢谢@Koolinc