【问题标题】:Set "this" variable easily?轻松设置“this”变量?
【发布时间】:2010-10-02 04:49:00
【问题描述】:

我对 Javascript 有很好的了解,但我想不出一个设置“this”变量的好方法。考虑:

var myFunction = function(){
    alert(this.foo_variable);
}

var someObj = document.body; //using body as example object
someObj.foo_variable = "hi"; //set foo_variable so it alerts

var old_fn = someObj.fn;   //store old value
someObj.fn = myFunction;   //bind to someObj so "this" keyword works
someObj.fn();              
someObj.fn = old_fn;       //restore old value

有没有办法在没有最后 4 行的情况下做到这一点?挺烦人的……我试过绑定一个匿名函数,我觉得很漂亮也很聪明,但是没用:

var myFunction = function(){
    alert(this.foo_variable);
}

var someObj = document.body;        //using body as example object
someObj.foo_variable = "hi";        //set foo_variable so it alerts
someObj.(function(){ fn(); })();    //fail.

显然,将变量传递给 myFunction 是一种选择......但这不是这个问题的重点。

谢谢。

【问题讨论】:

    标签: javascript variables scope this


    【解决方案1】:

    在 JavaScript 中为所有函数定义了两种方法,call()apply()。函数语法如下:

    call( /* object */, /* arguments... */ );
    apply(/* object */, /* arguments[] */);
    

    这些函数所做的是调用它们被调用的函数,将 object 参数的值分配给 this

    var myFunction = function(){
        alert(this.foo_variable);
    }
    myFunction.call( document.body );
    

    【讨论】:

    • 另外,如果你使用 jQuery,你可以使用$.proxy(function, element),这样每当调用该函数时,它就会在 element.context 中。 api.jquery.com/jquery.proxy
    • 另一个有用的方法是.bind()
    【解决方案2】:

    我想你在找call

    myFunction.call(obj, arg1, arg2, ...);
    

    这会调用myFunction,并将this 设置为obj

    还有一个稍有不同的方法apply,它把函数参数当作一个数组:

    myFunction.apply(obj, [arg1, arg2, ...]);
    

    【讨论】:

    【解决方案3】:

    如果您想将this 值“存储”到函数中,以便以后可以无缝调用它(例如,当您无法再访问该值时),您可以bind 它(不可用但在所有浏览器中):

    var bound = func.bind(someThisValue);
    
    // ... later on, where someThisValue is not available anymore
    
    bound(); // will call with someThisValue as 'this'
    

    【讨论】:

    • 仅供参考 bind 显然可用于 IE9+、FF4+、Safari 5.1.4+ 和 Chrome 7+ (source)。您也可以直接在匿名函数上调用 bind:var myFunction = function(){ /* this = something */ }.bind(something);
    【解决方案4】:

    我对如何绑定 this 的搜索把我带到了这里,所以我发布了我的发现:在“ECMAScript 2015”中,我们还可以使用箭头函数在词法上设置它。

    见:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

    代替:

    function Person() {
      setInterval(function growUp() {
        // The callback refers to the `self` variable of which
        // the value is the expected object.
        this.age++;
      }.bind(this), 1000);
    }
    

    我们现在可以这样做了:

    function Person(){
      this.age = 0;
    
      setInterval(() => {
        this.age++; // |this| properly refers to the person object
      }, 1000);
    }
    
    var p = new Person();
    

    【讨论】:

      【解决方案5】:

      在javascript中设置this关键字。

      Javascript 有 3 种内置方法可以方便地设置 this 关键字。它们都位于Function.prototype 对象上,因此每个函数都可以使用它们(因为每个函数都通过原型继承从这个原型继承)。这些函数如下:

      1. Function.prototype.call():此函数将您要用作this 的对象作为第一个参数。然后其余的参数是被调用函数的各自参数。
      2. Function.prototype.apply():此函数将您要用作this 的对象作为第一个参数。然后第二个参数是一个数组,其中包含被调用函数的参数值(数组的第一个元素是函数的第一个参数,数组的第二个参数是函数的第二个参数等)。
      3. Function.prototype.bind():此函数返回一个新函数,它具有不同的值 this。它将您要设置为this 值的对象作为第一个参数,然后返回一个新的函数对象。

      调用/应用和绑定的区别:

      • callapply 的相似之处在于它们立即调用函数(预定义值为this
      • bindcallapply 的不同之处在于,此函数返回一个新函数,该函数与 this 值的不同绑定。

      示例:

      const thisObj = {
        prop1: 1,
        prop2: 2,
      };
      
      function myFunc(arg1, arg2) {
        console.log(this.prop1, this.prop2);
        console.log(arg1, arg2);
      }
      
      // first arg this obj, other arguments are the  
      // respective arguments of the function
      myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');
      
      // first arg this obj, other argument is an array which  
      // are the respective arguments of the function
      myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);
      
      
      // the bind method returns a new function with a different
      // this context which is stored in the newMyFunc variable
      const newMyFunc = myFunc.bind(thisObj);
      
      // now we can call the function like a normal function 
      newMyFunc('first', 'second');

      【讨论】:

        猜你喜欢
        • 2015-07-11
        • 2013-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-24
        相关资源
        最近更新 更多