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

    this的绑定规则

    1 默认绑定:

    function foo(){
        console.log(this.a);
    }
    var a = 2 ;
    foo(); // 2

    调用 foo() 的时候其实相当于 window.foo(),所以 this.a 其实指向的是 window.a

    2 隐式绑定

    function foo(){
        console.log( this.a );
    }
    var obj1 = {
        a: 2,
           obj2: obj2
    };
    var obj2 = {
        a: 42,
           foo: foo
    };
    obj1.obj2.foo(); // 42

    当函数引用有上下文对象时,隐式绑定规则会把函数调用中的 this 绑定到这个上下文的对象。因为调用 foo() 时 this 被绑定到 obj,因此 this.a 和 obj.a 是一样的

    对象属性引用链中只有上一层或者说最后一层在调用位置起作用(这里是由于作用域链对于 this 的寻找只会到当前的活动对象或变量对象中,不会到上一层)

    3 显式绑定

    function foo(){
        console.log( this.a );
    }
    var obj = {
        a: 2,
    };
    var bar = function(){
        foo.call( obj );
    };
    bar(); // 2
    setTimeout(bar,100) // 2
    
    // 显示绑定的 bar 不可能再修改它的 this
    bar.call(window); // 2

    即使用 apply() 和 call() 方法。它们的第一个参数是一个对象,在调用函数时将其绑定到 this。他们的主要区别就是第二个参数。
    我们创建了函数 bar(),并在内部调用了 foo.call(obj),因此强制把 foo 的 this 绑定到了 obj。之后无论如何调用 bar(),它总会手动在 obj 上调用 foo。这种绑定是一种强制绑定,也成为硬绑定。
    由于硬绑定是一种非常常用的模式,所以 ES5 提供了 bind() 函数。用法如下

    function foo(something){
        console.log( this.a, something );
        return this.a + something;
    }
    var obj = {
        a:2
    }
    var bar = foo.bind( obj );
    var b = bar(3); // 2 3;
    console.log(b); // 5

    4 new 绑定
    使用 new 调用函数只是对函数的 " 构造调用 ",所有的函数都可以使用 new 来调用。
    使用 new 来调用函数时,会自动执行如下操作

    创建(或者说构造)一个全新的对象
    这个新对象会被执行 [[Prototype]] 连接
    这个新对象会绑定到函数调用的 this
    如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象
    用代码表示就是如下步骤

    function foo(a){
        this.a = a;
    }
    var bar = new foo(2);
    console.log(bar.a); // 2
    // 其中 new foo(2) 进行的是类似如下的操作
    {
        var obj = new Object();
        obj.__proto__ = foo.prototype;
        var result = foo.call(obj,"2");
        return result === 'object' ? result : obj
    }

    使用 new 来调用 foo( … ) 时,我们会构造一个新对象并把它绑定到 foo( … ) 调用中的 this

    以上几种方式的优先级:
    【1】是否是new绑定?如果是,this绑定的是新创建的对象var bar = new foo();
    【2】是否是显式绑定?如果是,this绑定的是指定的对象var bar = foo.call(obj);
    【3】是否是隐式绑定?如果是,this绑定的是属于的对象var bar = obj1.foo(); 
    【4】如果都不是,则使用默认绑定 var bar = foo();

  • 相关阅读:
    win7系统如何一键清理系统垃圾【系统天地】
    win7无法正常关机的解决方法【系统天地】
    win10系统开机停在请稍候解决教程【系统天地】
    Win7系统一直提示盗版怎么办【系统天地】
    windows8 flash修复怎么操作【系统天地】
    win7电脑运行速度慢如何解决【系统天地】
    Win10系统如何自动清理垃圾缓存文件【系统天地】
    Win7启用NFS服务设置的方法【系统天地】
    win7系统获得管理员取得所有权的方法【系统天地】
    Ubuntu16.04+hadoop2.7.3环境搭建
  • 原文地址:https://www.cnblogs.com/darkbluelove/p/11338303.html
Copyright © 2011-2022 走看看