zoukankan      html  css  js  c++  java
  • js中this的绑定

    人们对于this的绑定常常有两个误解,一:指向函数本身,二:指向函数作用域。这两种想法都是错的,this并不指向函数本身,也不指向函数作用域。

    复制代码
    function foo(){
    this.count++;
    }
    foo.count = 0;
    for(var i = 0 ; i<5 ; i++){
    foo();
    }
    alert( foo.count ); // 0
    复制代码
    因为this不指向函数本身,所以foo.count的值依然是0。

    function foo(){
    var a = 1 ;
    alert(this.a);
    }
    var a = 2;
    foo(); // 2
    因为this不指向函数作用域,所以输出的是2。

    this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
    
    this的绑定一共有四种绑定:1:默认绑定(即没有明确的调用对象)
    
                                        2:隐性绑定(即作为对象方法调用,this会被绑定到该对象)
    
                                        3:显性绑定(使用apply()和call()调用,两个方法的第一个参数为一个对象,this被绑定到该对象)  
    
                                        4:new绑定(使用new来调用函数,会构造一个新对象,并且把this绑定到该对象)
    
      一:默认绑定   (即没有明确的调用对象)     
    

    function foo(){
    var a = 1 ;
    alert(this.a);
    }
    var a = 2;
    foo(); // 2 (非严格模式下)
    没有明确调用对象,this会被绑定到window对象,所以this.a就是window.a,即为2。不过这得在非严格模式下,只有在非严格模式下this才会被绑定到window对象,而在严格模式下,this被绑定到undefined。

       二:隐性绑定   (即作为对象方法调用,this会被绑定到该对象)
    

    复制代码
    function foo(){
    var a = 1;
    alert(this.a);
    }
    var obj = {
    a:2,
    foo:foo
    };
    obj.foo(); // 2
    复制代码
    obj对象调用foo()函数,this被绑定到obj对象,所以输出了obj对象的a的值2。

     对象属性引用链中只有最后一层会影响调用位置
    

    复制代码
    function foo(){
    alert(this.a);
    }
    var obj2 = {
    a:2,
    foo:foo
    };
    var obj1 = {
    a:1,
    obj2:obj2
    };
    obj1.obj2.foo(); //2
    复制代码
    obj1和obj2两个对象连续调用,this会被绑定到最后一个对象,即obj2,所以输出2

    隐式丢失:被隐式绑定的函数会丢失绑定对象,有两种情况会丢失,一种为引用,另一种为回调函数。
    
         引用:
    

    复制代码
    function foo(){
    alert(this.a);
    }
    var obj = {
    a:1,
    foo:foo
    };
    var bar = obj.foo;
    var a = "global 1";
    bar(); //global 1
    复制代码
    bar是obj.foo的一个引用,实际上它引用的是foo函数本身,所以this被绑定到window对象,输出的是"global 1"

       回调函数:
    

    复制代码
    function foo(){
    alert(this.a);
    }
    function doFoo(fn){
    fn();
    }
    var obj = {
    a = 1,
    foo:foo
    }
    var a = "global 1";
    doFoo(obj.foo); //"global 1"
    复制代码
    调用回调函数的函数可能会修改this

     三:显性绑定(使用apply()和call()调用,两个方法的第一个参数为一个对象,this被绑定到该对象) 
    

    复制代码
    function foo(){
    alert(this.a);
    }
    var obj = {
    a:1
    };
    foo.call(obj); // 1
    复制代码
    call()的参数若为空,默认调用window对象,若为一个原始值(字符串类型,布尔类型或者数字类型),则这个原始值会被转换成它的对象形式(new String(),new Boolean() 或者 new Number()),这被称为“装箱”

     硬绑定———显示绑定的一种变形
    
            优点:可以解决丢失绑定问题
    
            缺点:硬绑定后不可能再修改它的this   
    

    复制代码
    function foo(){
    alert(this.a);
    }
    var obj = {
    a:2
    };
    var bar = function(){
    foo.call(obj);
    };
    bar(); // 2
    setTimeout(bar,100); // 2
    bar.call(window); // 2
    复制代码
    ES5中提供了内置方法Function.prototype.bind

    复制代码
    function foo(something){
    alert(this.a, something);
    return this.a + something;
    }
    var obj = {
    a:2
    };
    var bar = foo.bind(obj);
    var b = bar(3); // 2 3
    alert(b); // 5
    复制代码
    bind()会返回一个硬编码的新函数,它会把参数设置为this的上下文并调用原始函数

    四:new绑定(使用new来调用函数,会构造一个新对象,并且把this绑定到该对象)

    function foo(a){
    this.a = a;
    }
    var bar = new foo(2);
    alert(bar.a); // 2

    this绑定的四条规则的优先级: new绑定 > 显示绑定 > 隐式绑定 > 默认绑定

  • 相关阅读:
    long和Long的区别
    C语言的变量的内存分配
    Java蓝桥杯 算法提高 九宫格
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
  • 原文地址:https://www.cnblogs.com/libin-1/p/5745696.html
Copyright © 2011-2022 走看看