Js传参方式
Js中的传参方式也有两种:by value
和 by sharing
这两种。说白了前者传值,后者传址。By value是对于原始数据类型,例如int,char之类的;而By sharing 和By reference是对于高级数据结构,如Object,struct之类。我们可以想象到一个Object或是struct 不能仅仅通过传值进行传参。当然啦,我们能够很容易明白 by sharing
和 by value
的区别,但是 by sharing
和 by reference
的区别却不一定能够明了,看下面一个例子:
var bar;
var foo = bar;
bar = {'key':'value'};
console.log(foo, bar);
// result
undefined Object {key: "value"}
如上,By sharing 中foo 是undefined , bar 是{'key' : 'value'}; 而 By reference 则应该两者都是{'key' : 'value'}。
Js作用域
每个函数在创建完成时,它有三个重要的内置属性也同时被创建:
{
AO // 记录自己函数本身内的变量,参数等信息
this // 就是在调用 this.xx 时的那个家伙
scope // 指向外层函数 AO 的一个链(在实现的时候可能通过数组)
}
在Js中,我们经常讲的作用域 = SCOPE应该是这样的:
SCOPE = AO + scope
回到闭包问题上,下面的代码展示了最基础的循环引用问题:
for (var i=0; i<link.length; i++) { // window scope
link[i].onclick = function() { // inner function
alert(i);
};
}
// inner function's SCOPE is as follow:
{
AO
this // 等于 link[i]
scope // 指向 window 的记录,包括我们需要的变量 i
}
// for 循环的执行会立即执行完毕,所以当内层函数在 onclick 被触发时,
// inner function 查找变量 i 时,会在 AO + scope 中找,AO 中没有,
// 而 scope 中的变量 i 现在都已经成为 link.length 了,杯具了吧。
// 输出结果应该不用我讲了吧!:)
利用闭包写上面的程序那应该是:
for (var i=0; i<link.length; i++) { // window scope
link[i].onclick = (function(i) { // outer function
return function() { // inner function
alert(i);
};
})(i);
}
// inner function's SCOPE:
{
AO // no important info
this // we don't care it
scope // outer function & window scope
}
// outer function's SCOPE
{
AO // 包含参数 i
this // we don't care it
scope // window scope
}
这时,如果inner function被触发,他会从自己的AO以及scope(outer function的AO 和 window scope)中找寻变量i,可以看到outer function的AO中已经包含了i,而且对于这个for循环,会有对应有N个(function(){})() 被创建执行。所以每个inner function都有一个特定的包含了变量 i 的outer function。