彻底明白js中的this指向问题

文章原地址 https://www.jianshu.com/p/59be7936c345

this指向问题

    var obj = {  
        foo:  function () {
            console.log(this.bar)
        },
        bar: 1
    };

    var foo = obj.foo;
    var bar = 2;
        // 写法一

    obj.foo(); //1

        // 写法二
    foo(); //2

虽然obj.foo和foo指向同一个函数,但执行结果却不一样,这种差异的原因就是因为在函数内部使用了this关键字,很多教科书会告诉你,this是函数运行时所在的环境,对于obj.foo()来说,foo运行在obj环境,所以this指向obj,对于foo()来说,foo()运行在全局环境,所以this指向全局环境,所以,两者运行结果不一样

下面思考一下:为什么obj.foo()就是在obj环境执行,而一旦var foo = obj.foo; foo()就变成了在全局环境中执行,本文就解释一下javascript这样处理的原理

内存的数据结构

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

var obj = {foo: 5}
上面的代码将一个对象赋值给变量obj,js引擎会先在内存里面,生成一个对象{foo: 5},然后把这个对象的内存地址赋值给变量obj,也就是说,变量obj是一个地址,后面如果要读obj.foo,引擎先从obj拿到内存地址,然后再从该地址中读取原始的对象,返回他的foo属性
原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象,例如:上面foo属性,实际上是以这种形式保存的

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

函数

var obj1 = {
        foo: function () {
            console.log(111)
        }
    }
    这时,引擎会将函数单独保存在内存中,然后将函数的地址赋值给foo属性的value属性     //例如:
     {
         foo: {[[value]]: 函数的地址}
     }  
    由于函数是一个单独的值,所以他可以在不同的环境(上下文)执行

var f = {
    name: '王淼',
    foo: function() {
        console.log(this.name)
    }
}
f.foo()
var obj = f.foo;
var name = 'nihao'
obj()
所以说虽然f.foo和obj指向同一个函数,但执行的结果不同

环境变量

js 允许在函数体内部,引用当前环境的其他变量
var f = function () {
console.log(x)
}
上面代码中引用了变量x,该变量由运行环境提供,那么问题来了,由于函数可以在不同的运行环境执行,所以需要一种机制,能够在函数体内部获得当前的执行环境,所以,this就出现了,他的设计目的就是在函数体内部,指代当前的运行环境

    var f = function () {
        console.log(this.x)
    }
     上面代码中。函数体内的this.x就是指当前运行环境的x
    var x = 1;
    var obj = {f: f,x: 2}
    //单独执行
    f(); //1
    //环境执行
    obj.f() //2
    上面代码中,函数f在全局环境执行,this.x指向全局环境的x
    相当于在, 内存中存储函数,将函数的地址赋值给f变量,变量f指向函数本身,所以在全局环境下执行,而{f: f ,x: 2}会存到内存中,将对象的地址赋值给obj,所以obj.f是通过obj找到f,所以就是在obj环境下执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值