美文网首页
2019-02-15

2019-02-15

作者: 饭贩飯販帆 | 来源:发表于2019-02-15 16:25 被阅读0次

    JavaScript 语言之所以有 this 的设计,跟内存里面的数据结构有关系。

    var obj = { foo: 5 };
    上面的代码将一个对象赋值给变量obj。JavaScript 引擎会先在内存里面,生成一个对象{ foo: 5 },然后把这个对象的内存地址赋值给变量obj。也就是说,变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj拿到内存地址,然后再从该地址读出原始的对象,返回它的foo属性。

    原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象。举例来说,上面例子的foo属性,实际上是以下面的形式保存的。

    {
    foo: {
    [[value]]: 5
    [[writable]]: true
    [[enumerable]]: true
    [[configurable]]: true
    }
    }
    注意,foo属性的值保存在属性描述对象的value属性里面。

    这样的结构是很清晰的,问题在于属性的值可能是一个函数。

    var obj = { foo: function () {} };
    这时,引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo属性的value属性。

    {
    foo: {
    [[value]]: 函数的地址
    ...
    }
    }

    避免多层 this
    由于this的指向是不确定的,所以切勿在函数中包含多层的this。

    var o = {
    f1: function () {
    console.log(this);
    var f2 = function () {
    console.log(this);
    }();
    }
    }

    o.f1()
    // Object
    // Window
    上面代码包含两层this,结果运行后,第一层指向对象o,第二层指向全局对象,因为实际执行的是下面的代码。

    var temp = function () {
    console.log(this);
    };

    var o = {
    f1: function () {
    console.log(this);
    var f2 = temp();
    }
    }

    一个解决方法是在第二层改用一个指向外层this的变量。

    var o = {
    f1: function() {
    console.log(this);
    var that = this;
    var f2 = function() {
    console.log(that);
    }();
    }
    }

    o.f1()
    // Object
    // Object
    上面代码定义了变量that,固定指向外层的this,然后在内层使用that,就不会发生this指向的改变。

    事实上,使用一个变量固定this的值,然后内层函数调用这个变量,是非常常见的做法,请务必掌握。

    相关文章

      网友评论

          本文标题:2019-02-15

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