简体   繁体   English

传递方法名称作为VS的回调。 用讨厌的功能包装它

[英]Passing method name as a callback VS. wrapping it with annoymous function

I have a button #test. 我有一个#test按钮。

var obj = {
  name: "John",
  test: function() {
    console.log('name '+ this.name );
  }
};

$("#test").on( "click", obj.test);

This will log an empty string (logging typeof this.name gives a string). 这将记录一个空字符串(记录typeof this.name给出一个字符串)。

Edit: I understand this context becomes the button, hence this.name returns nothing. 编辑:我知道上下文成为按钮,因此this.name不返回任何内容。

Versus

var obj = {
  name: "John",
  test: function() {
    console.log('name '+ this.name );
  }
};

$("#test").on( "click", function() {
  obj.test();  //logs John
});

What is the difference? 有什么区别?

Edit: How does wrapping obj.test() with an annon function make it behave differently than above? 编辑:如何用Annon函数包装obj.test()使其行为与以上有所不同?

The real difference is what object test is operating on. 真正的区别是对象测试在进行什么操作。 When you call the function in the second example you are calling the function with the obj context. 在第二个示例中调用该函数时,您正在使用obj上下文调用该函数。 In the first example you are passing a reference to the function but not the context that it was attached to. 在第一个示例中,您传递的是对该函数的引用,而不是该函数附加到的上下文。 In the first case when the function is called it is actually operating the the global scope. 在第一种情况下,调用该函数实际上是在操作全局范围。

To test this out try putting: var name = "eiriki"; 要测试这一点,请尝试放置:var name =“ eiriki”; somewhere in global scope then running your function. 然后在全局范围内运行某个函数。 It will likely print out eiriki unless you have something else assigning to it already. 除非您已经分配了其他东西,否则它可能会打印出eiriki。

It's about resolving this . 关于解决this If you use $("#test").on("click", obj.test); 如果您使用$("#test").on("click", obj.test); then this will be the button but if you pass a closure then this will be obj . 那么this将是按钮,但如果你通过一个封闭那么this将是obj

When I call obj.test then this in test will be obj. 当我打电话obj.test那么this测试将OBJ。

JQuery will set this to be the button when it's clicked so passing obj.test without a reference to obj being this will break your obj.test function. jQuery将设置this是当它被点击,从而通过obj.test没有提及OBJ是按钮this会破坏你的obj.test功能。

The best way to resolve this problem is to use Function.prototype.bind (you need the polyfil for IE < 9): 解决此问题的最佳方法是使用Function.prototype.bind (您需要IE <9的polyfil ):

var obj = {
    name: "John",
    test: function () {
        console.log('This is:' + this.toString());
    },
    toString: function () {
        return "It's test"
    }
};

$("#test").on("click", function () {
    // by the way; this here is the button
    console.log("what's this here:", this.toString());
    obj.test();  //works but creates a closure
});

$("#test").on("click", obj.test);//breaks, this will be button in test

$("#test").on("click", obj.test.bind(obj));//works

// now to show how this is resolved
window.mytest = obj.test;
window.mytest();// this is window
var obj2 = {
    toString: function () {
        return "this is obj2";
    }
};
obj2.test = obj.test;
obj2.test();//this is obj2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM