• js——this


    每个函数的this是在调用时绑定的,完全取决于函数的调用位置  

         1. 绑定规则总结        

    一般情况下,按下列顺序从下至上来判断this的绑定对象(绑定的优先级从下至上递减

    • 默认:在严格模式下绑定到undefined,否则 绑定到全局对象
    • 隐式:由上下文对象调用?绑定到对应的上下文对象
    • 显示:由call或apply或bind调用?绑定到指定的对象
    • new:由new调用?绑定到新创建的对象

         2. 绑定规则说明     

    • 默认情况
      • 规则:非strict mode时,绑定到全局;strict mode时,绑定到undefined
      • 适用情况:当其它三种规则不适用时使用
    var a = 2;
    function f1(){
        alert(this.a);
    }
    function f2(){
        var a = 3;
        f1();
    }
    f2();//输出为2,全局定义的
    View Code
    • 绑定到上下文对象(隐式绑定)
      • 函数作为对象的一个属性,则该对象就是该函数的上下文对象
    function foo(){
        alert(this.a);
    }
    var obj2 = {
        a:42,
        foo:foo//foo作为obj2的属性
    };
    var obj1 = {
        a:2,
        obj2: obj2
    };
    obj1.obj2.foo();//输出obj2中的42,obj2是foo对象属性引用链中的最后一层
    View Code
      • 隐式绑定丢失:函数作为对象的属性不代表函数属性完全属于该对象,它还是独立的。当直接引用函数时,它会用默认绑定方式(全局或undefined)
    var obj = {
        a:"obj",
        foo:function(){
            alert(this.a);
        }
    }
    var a = "global"
    var bar = obj.foo;//bar直接引用函数
    bar();//输出"global"
    View Code
    • 显式绑定
      • 函数不属于一个对象的属性,可利用call、apply、bind函数让this绑定到该对象上
      • foo.call(obj, param):call函数会把第一个变量obj绑定到foo函数的this上
    function foo(){
        alert(this.a);
    }
    var obj = {//对象中没有foo属性
        a:"obj"
    };
    foo.call(obj);//输出obj
    View Code
      • foo.apply(obj, param):apply函数的效果和使用与call相似
      • 硬绑定方法bind:newFoo = foo.bind(obj); 将foo的this绑定到obj上,并返回相应的新函数,这样就不会发生绑定丢失了
    function foo(){
        alert(this.a);
    }
    var obj = {
        a:"obj"
    };
    var obj2 = {
        a:"obj2"
    };
    var bar = foo.bind(obj);//bind把foo的this绑定到obj对象,并返回这个函数
    bar();//输出"obj"
    bar.call(obj2);//仍然输出"obj",硬绑定不会被修改
    View Code
      • 自定义一个bind函数:对apply、call函数进行封装,并返回一个新函数(已经绑定好对象)
    function foo(){
        alert(this.a);
    }
    //对apply函数进行封装,让绑定在bind内部完成,并返回一个函数
    //这样,就不能通过封装后的函数修改绑定
    function bind(fun, obj){
        return function(){  
            //apply函数返回值为undefind
            fun.apply(obj, arguments);
        };
    }
    var obj = {
        a:"obj"
    }
    var bar = bind(foo, obj);
    bar();//输出"obj"
    bar.apply(window);//仍然输出"obj"
    View Code
    • new绑定
      • new foo(); 用new调用一个函数时,它会把foo的this绑定到创建的新对象
    function foo(a){
        this.a = a;
    }
    var bar = new foo(2);
    alert(bar.a);//输出 2
    View Code

         3. 特殊情况     

    • null和undefined传给call、apply、bind时,使用默认绑定规则。在做柯里化时可以用到
    • 为了不让这种情况下的this绑定到全局(从而影响全局的值),可以自定义一个空对象,并将它作为这几个函数的第一个参数
    • 软绑定:如果this绑定到全局或undefined,那就让它绑定到给定的对象,否则不变
    • 箭头函数:箭头函数的this绑定对象与其外层作用域是一致的

    参考:

    1. 《你不知道的javascript》上卷 

  • 相关阅读:
    PHP面试:实现动态获取函数参数的方法
    PHP面试:什么是类的多态性,请写出一个例子
    php相关操作
    客户端app支付宝登录接口
    商品分类设计
    Git连接远程服务器
    iptables/mysql设置指定主机访问指定端口
    CMake安装grpc生成gRPCTargets.cmake文件
    Linux下Springboot解决`APR based Apache Tomcat Native library`提示
    java双重检测或枚举类实现线程安全单例(懒汉模式)
  • 原文地址:https://www.cnblogs.com/coolqiyu/p/7135952.html
Copyright © 2020-2023  润新知