zoukankan      html  css  js  c++  java
  • JS简记-this

    this的绑定和函数声明的位置没有任何关系(这是与词法作用域最大的不同),取决于函数的调用方式,函数不同的调用方式,决定了函数内this的绑定对象。

    函数有4种不同的调用方式:

    function foo(){
        //...
    }
    foo()//1
    var o = Object.create(null);
    o.foo = foo;
    o.foo();//2
    foo.call(window)//3,或者foo.apply(window)
    new foo()//4

     第一种调用foo()会进行默认绑定,即foo中的this会绑定到全局对象(window)上。

    function foo(){
        console.log(this.a);
    }
    var a = 1;//全局作用域声明的变量,会自动成为全局对象的属性
    foo();//1

    如果使用“use strict”则会绑定到undefined。

    function foo2(){
        "use strict"
        console.log(this.a);
    }
    foo2();//TypeError,如果不使用use strict则会输出undefined

    第二种隐式绑定,即通过对象调用函数,使得函数内的this绑定在该对象上。

    function foo(){
        console.log(this.a);
    }
    var o = {
        a: 1,
        foo: foo
    };
    o.foo();//1

    第三种显式绑定,即通过call、apply将函数与指定对象进行绑定(实际上就是将this绑定到指定对象上)。

    function foo(){
        console.log(this.a);
    }
    var o = {
        a: 1
    }
    foo.call(o);//or foo.apply(o)

    call和apply在绑定后会立即调用,且原函数的绑定策略并没有随之改变,准确的说应该是一种显示临时绑定,bind则会新生成一个函数,该函数会绑定在指定对象上,且绑定策略无法再被修改。

    function foo(b, c){
        console.log(this.a, b, c);
    }
    var o = {
        a: 1
    }
    var b = 2;
    var c = 3;
    var bar = foo.bind(o, b);//柯里化
    bar(c);//1 2 3
    bar.call(window, c);//1 2 3,this仍然绑定在o上

    第四种new绑定,即通过new关键字来调用函数,调用过程会发生以下逻辑:

    1. 创建(或者说构造)一个全新的对象。
    2. 这个新对象会被执行[[原型]]连接。
    3. 这个新对象会绑定到函数调用的this。
    4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。

    function foo(){
        this.a = 1;
        this.b = function(){
            console.log(this.a);//如果直接输出a,则会抛ReferenceError,注意区分词法作用域和this
        };
    }//函数最终没有返回对象,则在new调用时,返回new自动生成的对象。
    var o = new foo();
    o.b();//1

    优先级:new>显式>隐式>默认

    ES6中引入了一个新的this策略,“箭头函数”,将this绑定在父级this所指的对象上,这个策略有点儿类似继承,也有点儿类似词法作用域(即向父级查找,注意,不是向父级作用域查找this,this不在作用域范畴内)。

    function foo(){
        return () => {
            console.log(this.a);
        };
    }
    var o = {a: 1};
    var bar = foo.call(o);
    bar();//1,虽然这里采用“默认绑定”形式来调用函数,但该函数使用“=>”,将this绑定在了声明位置的父级函数的this所指对象上。

    注意,这里所有的绑定规则都是在运行时动态绑定的,即便是“箭头函数”也是通过父级函数在运行时绑定this后,“箭头函数”才会绑定this,这是完全动态的。

  • 相关阅读:
    系统集成项目管理工程师计算题(成本管理计算)
    系统集成项目管理工程师计算题(进度管理计算)
    系统集成项目管理工程师计算题(期望值)
    系统集成项目管理工程师计算题(三点估算)
    系统集成项目管理工程师计算题(沟通渠道)
    Asp.net core web Api 应用Jwt 验证
    Linux vmstat命令
    关于Java集合的小抄
    @Resource和@Autowire
    Servlet是线程安全的吗?
  • 原文地址:https://www.cnblogs.com/holoyong/p/8975478.html
Copyright © 2011-2022 走看看