

// 求i的阶乘
function factorial(i){
if(i < 2){
return 1;
}
return i*factorial(i-1); // 递归调用
}
alert(factorial(5)); // 求5的阶乘
// 以上方式存在一个问题?如下:
var factorial = function(i){
if(i < 2){
return 1;
}
return i*factorial(i-1); // factorial还能被调用吗?不能
}
var test = factorial;
factorial = null;
alert(test(2));
// 解决方案:
var factorial = function(i){
if(i < 2){
return 1;
}
return i*arguments.callee(i-1); // arguments.callee返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文
}
var test = factorial;
factorial = null;
alert(test(5));作用域
// 在程序中,作用域控制着变量的可见性和生命周期。
var name = "default"; // 全局作用域
function getName(){
var name = "getName"; // getName作用域下
for(var i=0; i<2; i++){
var inName = "inName";
}
alert(i + "," + inName); // 2,inName 注意:在js中没有块级作用域,及if、for、while中声明的变量是放在块所在的作用域下
return name;
}
alert(getName()); // getName 注意:js存在函数作用域,所以在函数内部定义的变量在外部是不可见的
alert(name); // default注意:在现代的很多语言中,推荐将变量尽可能的延迟声明。如:java而在js中,却不推荐这样做,因为js不支持块级作用域。推荐在函数的开始就将所有用到的变量进行声明。
闭包
函数能够访问它被创建时环境的上下文称为闭包。作用域的好处是,内部函数可以访问外部函数的所有变量(除this和arguments)。
var myObject = {
value : 0,
increment : function(inc){
this.value = typeof inc === 'number' ? inc : 1;
},
getValue : function(){
return this.value;
}
};
myObject.increment(10);
alert(myObject.value);
alert(myObject.getValue());
// 上面使用字面常量方式定义了一个myObject对象。但是value变量可以被外部对象访问
var myObject = function(){
var value = 0;
return {
increment: function(inc){
value += typeof inc === 'number' ? inc : 1;
},
getValue : function(){
return value;
}
};
}();
myObject.increment(10);
alert(myObject.value); // 不能被外部对象访问
alert(myObject.getValue()); // 10
// 渐变body的背景色(黄色到白色)
var fade = function(node){
var level = 1;
var step = function(){
var hex = level.toString(16);
node.style.backgroundColor = '#FFFF' + hex + hex;
if(level < 15){
level += 1;
setTimeout(step, 500); // 如果level小于15,则内部函数自我调用
}
};
setTimeout(step, 1); // 调用内部函数
};
fade(document.body);
// 下面是一个很糟糕的例子
<a href="#" name="test">点击我...</a><br> // 点击时显示3
<a href="#" name="test">点击我...</a><br> // 点击时显示3
<a href="#" name="test">点击我...</a><br> // 点击时显示3
var add_the_handlers = function(nodes){
var i;
for(i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = function(e){ // 函数构造时的:i
alert(i);
};
}
};
var objs = document.getElementsByName("test");
add_the_handlers(objs);
// 造成上面的原因是:a标签的事件函数绑定了变量i,则不是函数在构造时的i值。
// 解决方案如下:
var add_the_handlers = function(nodes){
var i;
for(i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = function(i){
return function(e){
alert(i); // 回调(callbacks)
// data表示参数,而call_function则表示回调函数
function sendRequest(data, call_function){
// setTimeout来模仿客户端请求服务端中传输数据的时间。
// 当3秒钟后就调用回调函数(有客户端实现回调函数)
setTimeout(function(){
call_function(data); // 调用回调函数
}, 3000);
}
// 测试sendRequest函数
sendRequest("参数", function(context){
alert("context=" + context);
});