this: 当前执行上下文(global、function、eval)的一个属性,在非严格模式下总是指向一个对象;在严格模式下可以为任意值。

        全局上下文环境:
            在全局执行环境(在任何函数体外部)中,无论是否为严格模式,this都指向全局对象(在浏览器中全局对象为window;在Node环境中全局对象为globalThis);
        函数上下文环境:
            在函数内容,this的值取决于函数被调用的方式。
            在非严格模式下,直接调用f1函数,此时this的指向为全局对象,因为在浏览器中直接调用f1函数,相当于 window.f1();
            在严格模式下直接调用f2函数,此时this的值为undefined,因为在直接调用f2函数进入f2函数执行环境时没有设置this的值;
        类上下文环境:
            this在类中的表现与函数中相似,需注意的是:在类的构造函数中,this是一个常规对象;类中所有非静态方法都会被添加到this的原型中。

        在非严格模式下使用call()和apply()时,如果指定this的值(即call和apply方法中的第一个参数)不是对象,则会被尝试的转化为对象(如:7 --> New Number(7)),null 和 undefined 会被转化为全局对象。
            call() 和 apply() 方法的区别:call()方法传参数时直接写值,apply()方法传参数时需以数组的形式传递

        箭头函数中的this
            在箭头函数中,this与封闭词法环境中的this保持一致,不再取决于函数被调用时的环境,而是取决于箭头函数被创建时的环境.
            箭头函数中的this会被永久绑定到它外层函数的this。

        当函数作为对象里的方法被调用时,this 被设置为调用该函数的对象,且 this 的绑定只受最接近的成员引用的影响

        当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象
 
  
        function f1() {
            console.log(this);
        }

        f1();  // Window -- 浏览器中,相当于 window.f1(); globalThis  -- Node中

        function f2() {
            'use strict';  // 采用严格模式
            console.log(this);
        }

        console.log('直接调用f2');
        f2();  // undefined
        console.log('采用window.f2()');
        window.f2();  // Window

        console.log('====================================');

        var obj = {a: 'Custom'};
        var a = 'Global';
        function whatsThis() {
            return this.a;
        }
        console.log(whatsThis());  // Global
        console.log(whatsThis.call(obj));  // Custom
        console.log(whatsThis.apply(obj));  // Custom

        console.log('====================================');
        
        function add(c, d) {
            return this.a + this.b + c + d;
        }
        var o = {a: 1, b: 3};
        console.log(add.call(o, 5, 7));  // 1+3+5+7 = 16
        console.log(add.apply(o, [10, 20]));  // 1+3+10+20 = 34

        console.log('====================================');

        function f(){
            return this.a;
        }
        var g = f.bind({a:"azerty"});  // 变量 g 为一个函数,方法体内容同函数 f 一致,this被永久指向{a:"azerty"}对象
        console.log(g());  // azerty
        var h = g.bind({a:'yoo'});  // 变量 h 为一个函数,方法体内容同函数 g 一致
        console.log(h());  //  azerty  --  bind只生效一次!
        var o = {a:37, f:f, g:g, h:h};
        console.log(o.a, o.f(), o.g(), o.h());  // 37, 37, azerty, azerty

        console.log('====================================');

        var globalObject = this;
        var foo = (() => this);
        console.log(foo() === globalObject);  // true
        var obj = {foo: foo};
        console.log(obj.foo() === globalObject);  // true
        console.log(foo.call(obj) === globalObject);  // true
        foo = foo.bind(obj);
        console.log(foo() === globalObject);  // true

        console.log('====================================');

        var obj = {
            bar: function() {
                var x = (() => this);
                return x;
            }
        };
        var fn = obj.bar();  // fn 为箭头函数(() => this)
        console.log(fn() === obj);  // true
        var fn2 = obj.bar;  // fn2 为函数function() {var x = (() => this); return x;}
        console.log(fn2()() == window);  // true

        console.log('====================================');

        var o = {
            a: 10,
            b: 20,
            f: function() { 
                return this.a + this.b; 
            }
        };
        var p = Object.create(o);
        p.a = 1;
        p.b = 4;
        console.log(p.f());  // 5

        console.log('====================================');

        function sum() {
            return this.a + this.b + this.c;
        }

        var o = {
            a: 1,
            b: 2,
            c: 3,
            get average() {
                return (this.a + this.b + this.c) / 3;
            }
        };

        Object.defineProperty(o, 'sum', { get: sum, enumerable: true, configurable: true});

        console.log(o.average, o.sum);  // 2, 6    

  

posted on 2020-11-18 17:04  取名向来是件难事  阅读(116)  评论(0编辑  收藏  举报