javascript 闭包的理解(二)
2020-12-13 06:00
标签:代码 this 而且 etag 上下文 closure 代码生成 就会 use 上面的这段代码(我们叫它代码段A吧)里, user.getage.call(window) 和 user.getage.call({age: 23}) 返回的结果,虽然在意料之中,但是我却并不非常清楚的知道为什么是这样。 我只是大概的知道,之所以是这个结果,肯定跟User构造函数里的闭包有关系。 我认为User构造函数里有两个闭包,所以我猜想调用user.getage的时候,就生成了2个闭包作用域。 输出如下: 从输出的对象结构,可以看到这个方法它的[[Scopes]]确实有两个Closure,而且每个Closure里面有些什么东西也显示出来了。 我猜想在执行getage方法时,会先执行第一个闭包作用域,也就是Closure 0,这个闭包是由代码段A里的以下代码生成的: 我觉得这里应该搞清楚闭包、闭包作用域、闭包包含的作用域 三个概念,否则理解起来会很蒙,搞不清楚。 闭包作用域:就是由以上代码生成的执行上下文空间,它就是对象结构图中的那个[[Scopes]]。 闭包包含的作用域:可以看到[[Scopes]]里面还包含了getage闭包引用的另外两个闭包的作用域里的变量:立即执行函数的作用域里的变量p 和 User函数作用域里的变量i和变量properties。 从对象结构里可以看到,闭包 Closure 0 里面存在一个变量p,因此执行闭包时,会去闭包作用域里搜索p,但搜索不到,因为p是在立即执行函数的作用域里定义的,所以会立即进入搜索Closure 0作用域的流程。 搜索Closure 0时,找到了p,并且发现p = i,此时p的定义找到了,但p等于i,所以进入搜索变量i的定义的流程。 因为变量i没有在立即执行函数里定义,所以Closure(User)被保留了下来,在立即执行函数的作用域里找不到变量i,就进入Closure(User)作用域寻找,找到了i,同时应为是立即执行函数,所以i的值一搜索到,就理解返回给p,并存入Closure 0作用域中,而Closure(User)中的i的值由于程序继续执行而变化,最后只会存入最后设置给i的值。 properties的值也是一样,在闭包作用域里找不到,就会去立即执行函数的作用域里找,找不到再去Closure(User)里找,找到了立即返回。 所以上面那段生成闭包 Closure 0 的代码执行后,返回的结果就是 properties[i],此时闭包作用域使用完毕,不再需要,可以回收,进入解析Closure(User)作用域的步骤。 然后properties[i] 被解析为 properties[“age”],然后被返回。 javascript 闭包的理解(二) 标签:代码 this 而且 etag 上下文 closure 代码生成 就会 use 原文地址:https://www.cnblogs.com/macliu/p/11161414.html // 定义一个User构造函数
function User(properties){
//遍历对象属性,确保它作用域正确
for(var i in properties){
(function(which){
var p = i;
//为属性创建获取器
which["get"+i] = function(){
return properties[p];
};
//为属性创建设置器
which["set"+i] = function(val){
properties[p] = val;
//return properties[p];
};
})(this);
}
}
// 创建一个User实例
var user = new User({
name:"Bob",
age:44,
islive:true,
money:50000,
earn:5000,
nation:"china",
job:"web Dev"
});
user.getname(); // 返回 "Bob"
user.getage(); // 返回 "44"
user.getage.call(window); // 依然返回44
user.getage.call({age: 23}); // 还是返回44
但这只是我的猜想,事实是不是这样的呢?我想到了一个办法来验证:使用console.dir()var getage = user.getage;
console.dir(getage);
which["get"+i] = function(){
return properties[p];
};
闭包:就是以上代码所定义的函数which[“get”+i]。