美文网首页
this解读

this解读

作者: 熬得萨菲 | 来源:发表于2020-02-06 19:58 被阅读0次

    规范解读this:

    基础类型(base) | 引用类型(reference)

    reference由三个组成部分,分别是:
    base value: 基础值(null,undefined,string,number,boolean,symbol, or an environment record(环境记录))其中的一种。
    referenced name: 属性名
    strict reference: 严格模式
    
    reference组成部分的方法:如GetBase和IsPropertyReference.
    1.GetBase
    返回reference的base balue
    
    2.IsPropertyReference
    如果base value是一个对象,就返回true;
    

    如何确定this的值:

    让我们描述一下:
    1.计算 MemberExpression 的结果赋值给 ref
    
    2.判断 ref 是不是一个 Reference 类型
    
    2.1 如果 ref 是 Reference,并且 IsPropertyReference(ref) 是 true, 那么 this 的值为 GetBase(ref)
    
    2.2 如果 ref 是 Reference,并且 base value 值是 Environment Record, 那么this的值为 ImplicitThisValue(ref)
    
    2.3 如果 ref 不是 Reference,那么 this 的值为 undefined
    

    举例:

    举最后一个例子:
    
    var value = 1;
    
    var foo = {
      value: 2,
      bar: function () {
        return this.value;
      }
    }
    
    //示例1
    console.log(foo.bar());//1
    //示例2
    console.log((foo.bar)());//1, 因为实际上()并没有对它进行计算
    //示例3
    console.log((foo.bar = foo.bar)());//2 .赋值的化会触发GetValue方法,所以返回的值不是reference类型,那么this的值就是undefined,在非严格模式下,this的值为undefined的时候,其值会被隐式地转换为全局对象。
    //示例4
    console.log((false || foo.bar)());//2 ; 用了GetValue方法,返回的不是reference类型,this为undefined
    //示例5
    console.log((foo.bar, foo.bar)());//2, 逗号操作符,也 用了GetValue方法,返回的不是reference类型,this为undefined
    
    补充:
    function foo() {
        console.log(this)
    }
    
    foo(); 
    MemberExpression 是 foo,解析标识符,查看规范 10.3.1 Identifier Resolution,会返回一个 Reference 类型的值:
    
    var fooReference = {
        base: EnvironmentRecord,
        name: 'foo',
        strict: false
    };
    因为 base value 是 EnvironmentRecord,并不是一个 Object 类型,还记得前面讲过的 base value 的取值可能吗? 只可能是 undefined, an Object, a Boolean, a String, a Number, 和 an environment record 中的一种。
    
    IsPropertyReference(ref) 的结果为 false,进入下个判断:
    
    2.2 如果 ref 是 Reference,并且 base value 值是 Environment Record, 那么this的值为 ImplicitThisValue(ref)
    
    base value 正是 Environment Record,所以会调用 ImplicitThisValue(ref)
    
    查看规范 10.2.1.1.6,ImplicitThisValue 方法的介绍:该函数始终返回 undefined。
    
    所以最后 this 的值就是 undefined。
    

    模拟实现call:

    call分为三步:

    1.将函数设为对象的属性 foo.fn = bar

    2.执行该函数 foo.fn()

    3.删除该函数 delete foo.fn;

    eg:
        var foo = {
            value : 1
        }
        function bar () {
            console.log(this.value)
        }
        bar.call(foo);
    
    也就是:
     var foo = {
         value:1,
         bar: function () {
             console.log(this.value)
         }
     }
    
     代码实现
     Function.prototype.myCall = function (obj) {//
         //1.首先要获取调用call的函数,用this获取
         obj.fn = this;
         //执行函数
         obj.fn();
         //删除删除
         delete obj.fn;
         
     }
    代码实现第二步,传参的时候
    var foo = {
        value: 1
    };
    
    function bar(name, age) {
        console.log(name)
        console.log(age)
        console.log(this.value);
    }
    
    bar.call(foo, 'kevin', 18);
    
    
    理解:
    arguments = {
        0: foo,
        1: 'kevin',
        2:  18,
        length: 3,
    }
    var argus = [];
    for(var i = 1 , len = arguments.length ; i < len ; i ++) {
        argus.push('arguments['+ i +']')
    }
    
    利用eval():参数是字符串,计算字符串并执行计算出来的值
    eval('obj.fn('+ argus +')')
    
    Function.prototype.myCall = function (obj) {
        obj.fn = this;
        var argus = [];
        for(var i = 1,len = obj.length; i < len; i++){
            argus.push('obj['+i+']')
        }
        eval('obj.fn('+argus+')');
        delete obj.fn;
    }
    
    
    最终版:当指向null的时候,视为指向window
    Function.prototype.call2 = function (obj) {
        //没有值的时候就指向window
        var obj = obj || window;
        obj.fn = this;
    
        var args = [];
        for(var i = 1, len = arguments.length; i < len; i++) {
            args.push('arguments[' + i + ']');
        }
    
        var result = eval('obj.fn(' + args +')');
    
        delete obj.fn
        return result;
    }
    
    

    相关文章

      网友评论

          本文标题:this解读

          本文链接:https://www.haomeiwen.com/subject/uxnuxhtx.html