在学习写轮播图,还有学习《js高级程序设计》中的执行环境,变量,作用域,函数,闭包时所想所感
下面我主要写的是变量的指向,变量指向的函数,变量指向的函数的执行,变量指向的函数执行时的作用域
先写一个超级简单的
function fn() {
var result = 1;
console.log(result);
return result;
}
var result1 = fn;
var result2 = fn();
console.log(result1,result2);
//结果
1
function fn() {
var result = 1;
console.log(result);
return result;
} 1
超级简单是吧,但是要明白这中间的过程是什么,一步步来:
- 定义了一个变量fn和一个函数,函数的内容是
var result = 1; ...
,将变量fn指向这个函数
算了还是稍微画个图吧
对于栈和堆还不是很了解
为了等下更好理解函数,这里的所有变量的值都当做引用类型,所有的变量都是指向,给变量加上()相当与执行变量所指向的函数
还是简单一点的
function fn() {
var result = [];
for (var i=0;i<3;i++) {
result[i] = function() {
return i;
}
}
return result;
}
var result1 = fn();
var result2 = result1[0]();
var result3 = result1[1]();
var result4 = result1[2]();
console.log(result1,result2,result3,result4);
// 结果
[function...,function...,function...] 3 3 3
- 将fn指向function(){var result = []...}
- 执行fn所指向的function,新建result,将result指向一个Array,将result[0]指向function(){return i;},result[1]指向另一个function(){return i;},result[2]也一样,虽然内容一样,不过这是不同的三个函数,返回result,这时result1指向result
- 执行result[0]所指向的函数,返回i,但是arguments没有,自己本身没有定义,所以根据作用域链,只能在上级函数中找到,这时候函数中的语句已经在第二步执行完毕,i=3,所以返回了3,result2就指向3,这下重点来了,这里就算是闭包的部分了,通常来说,当fn所指向的函数执行完毕后会销毁其活动对象,也就是定义的result,i等等,但是因为返回的result的词法作用域(lexcical scope)是在定义时确定的,(先不管with和trycatch),要用到i,这时就保留了上级函数的活动对象,以便于result所指向的函数访问,后面的两个相同
- 打印出他们指向的值
再看一个
function fn() {
var result = [];
for (var i=0;i<3;i++) {
result[i] = (function() {
return i;
})();
}
return result;
}
var result1 = fn();
var result2 = result1[0];
var result3 = result1[1];
var result4 = result1[2];
console.log(result1,result2,result3,result4)
// 结果
[0, 1, 2] 0 1 2
这次在result所指向的的函数后面加上了(),在result2,3,4后面取消了()
- 略
- 执行fn指向的函数,和上一次相同,定义函数,但是立即执行,这时result[0]就指向这个函数的的返回值,第一此循环i=1,执行一次function(){return i;},同样向上找到i=1,返回1,result[0]就指向1,后面的相同,然后返回result
- 这时候fn()就指向了在堆中的那个Array,result也就指向那个Array
- 打印
这下稍微难点的
function fn() {
var result = [];
for (var i=0;i<3;i++) {
result[i] = (function(i) {
return function() {
return i;
};
})(i);
}
return result;
}
var result1 = fn();
var result2 = result1[0]();
var result3 = result1[1]();
var result4 = result1[2]();
console.log(result1,result2,result3,result4)
// 结果
[function...,function...,function...] 0 1 2
- 略
- 执行fn指向的函数,和上一次相同,定义函数,立即执行,这时result[0]指向函数function(){return i};
,result[1]指向另一个function(){return i;},result[2]同上,返回result,是不是感觉和第一次一样,但是等下判断i的值就不一样了 - 执行result1[0]指向的函数function(){return i;},先在自己的作用域中找,没有,向上找,就是那个立即执行的函数中找,arguments中有,这时的i是3吗?显然不是的,是立即执行时传入的i,因为返回的function(){return i;}在定义时传入的0,所以这时的i为0,还记得刚才写的,词法作用域(lexcical scope)是在定义时确定的,
return fuction(){}
也可以理解为var anonymous = function(){}; return anonymous
;同理后面返回1和2 - 打印
网友评论