美文网首页
一个小小的JavaScript题目

一个小小的JavaScript题目

作者: 薯条你哪里跑 | 来源:发表于2018-12-06 11:00 被阅读0次

    原文:https://github.com/MrErHu/blog
    题目是这样的:

    var length = 10;
    function fn() {
        console.log(this.length)
    };
    var obj = {
        length: 5, 
        method: function (fn) {
            fn();
            arguments[0]();
            fn.call(obj, 12);
        }
    };
    obj.method(fn, 1);
    

    ============

    ===========

    =========

    =======

    ====

    ==
    答案是: 10 2 5
    让我们冷静分析下,首先介绍一下四种this的类型:
    默认绑定、隐式绑定、显示绑定 及 new绑定

    其中,默认绑定就是什么都匹配不到的情况下,非严格模式this绑定到全局对象window或者global,严格模式绑定到undefined;隐式绑定就是函数作为对象的属性,通过对象属性的方式调用,这个时候this绑定到对象;显示绑定就是通过apply和call调用的方式;new绑定就是通过new操作符时将this绑定到当前新创建的对象中,它们的匹配有限是是从小到大的。
    那么现在来解释一下:

    obj.method(fn, 12);

    上述执行其实对应的是下面三条语句:

    fn(); 
    arguments[0]();
    fn.call(obj, 1);
    

    通过将函数赋值给函数参数(fn),然后调用fn,这个时候能匹配到的this类型就是第一条默认绑定,因为实在非严格模式下,所以this绑定的是window,当然首先输出的是10。
      先解释一下第三个,这个也很简单,因为用了call,所以实际匹配了显示绑定,所以当前this绑定了obj,那么输出的肯定是2。
      下面着重解释一下第二个,这个我当时理解成和第一次完全一样,但实际并不是的,其实在JavaScript中数组算是一种特殊的对象(关于JavaScript对象的部分,我现在还在写,下一篇就会出的),arguments[0]其实就是通过对象的属性去调用(数组的默认属性类型是数值而普通对象的属性类型是字符串),那么现在其实运用的是规则2,this被绑定到arguments上,而arguments确实存在一个length属性,并且值为2(这个别告诉我你看不出来),所以输出的肯定就是2啦。
      可见《你不知道的JavaScript》这本书说的很对,之所以会在ES6出现箭头函数,实质就像用词法作用域代替this,因为这个真的特别特别容易误用和让人误解。

    相关文章

      网友评论

          本文标题:一个小小的JavaScript题目

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