有这么一段代码;
var x = 10;
//创建一个对象
var obj = {
x: 20,
f: function () {
console.log(this.x);
var that = this;
var foo = function(){
console.log(that.x);
}
foo();
}
};
obj.f();
首先要讲清楚两个基本概念.
1.在js中一切都是对象,函数也是对象,既然是对象那就有方法。对于函数对象来说,有一个call()
的方法,可以吧
2.js中变量的值,变量的值有基本类型值和引用类型值。基本类型值,像数据字符串之类的都是基本类型值。上面说过了既然在js中一切都是对象,变量也是对象,所以也有属性和方法。比如这样 var name="huangweidong";
这个时候如果给它一个属性再给个值,name.age="shamate"
。纵然不会出错,但是这句会被浏览器pass掉。由于js不能访问并对内存直接操作,而是通过引用。我是这么理解引用的,引用就是js和内存之间的桥梁(欢迎大神纠正错误)。变量其实就是一个有标识符或者id身份的字符串,当我们创建了一个新对象实例时(这时这个对象就会出现并保存在内存堆中)并把它保存在变量中时,变量中保存是什么不是对象的原型(保存在内存中的对象),保存的是引用也就是指针,这个指针指向内存中对象原型。所以当我们把对象复制到其他变量中时,复制的是引用也就是指针,而内存中的对象不被复制。但是基本类型值就不同了,是可以被复制的。
this
不就是指向对象嘛,它的值也是一个指针,当把this
复制给that
时,复制的是引用也就是指针。
console.log(this.x)
要找到x
就要从方法所处的对象的上下文去找,这儿我有个问题,当把对象obj
的x
属性删了之后,为什么控制台显示的是undefined
,不应该是继续往上找吗。*
1)上述代码在语法是有错误的,应该为
2)当obj.f()语句执行时,this为obj这个对象,这个对象上有属性x,故其
console.log(this.x)
输出为20
,内部的foo函数执行时,因为之前that已经通过that=this赋值语句指向了obj对象,因为闭包的关系,foo函数依旧能够访问到that变量,所以
console.log(that.x)
也是
20
3)在闭包环境下,this及arguments是不会到所处函数的外层函数寻找的
4)当obj的x属性被删除,也就是通过
delete obj.x
语句删除后再执行obj.f()
,此时this还是obj,其上的x属性已经不存在了,所以其输出为undefined