(第七章)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
//7.1 递归
function factorial(num){
if(num<=1){
return 1;
}else{
return num* factorial(num-1)
}
}
//下面调用会出错
var anotherFactorial = factorial;
factorial= null;
alert(anotherFactorial(4)); //报错
//arguments.callee是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用.
//严格模式下 grguments.callee报错
function factorial(num){
if(num<=1){
return 1;
}else{
return num* arguments.callee(num-1)
}
}
//函数表达式 ,kyi z可以再严格模式下运行
var factorial= (function f(num){
if(num<=1){
return 1;
}else{
return num* f(num-1)
}
})
//7.2 闭包
//闭包是指有权访问另一个函数作用中的变量的函数
function createComparisonFunction(propertyName){
return function(object1,object2){
var varlue1 = object[propertyName];
var varlue2 = object[propertyName];
if(varlue1<varlue2){
return -1;
}else if( varlue1 > varlue2){
return 1;
}else{
return 0;
}
}
}
//在函执行过程中,为读取和写入变量的值,就需要在作用域链中查找变量,
function conpare(value1,value2){
if(varlue1<varlue2){
return -1;
}else if( varlue1 > varlue2){
return 1;
}else{
return 0;
}
}
var result = compare(5,10);
///
var compare = createComparisonFunction("name");
var result = compare({name:"Nicholas"},{name:"greg"});
//创建函数
var compareNames = createComparisonFunction("name");
//d调用函数
var result = compare({name:"Nicholas"},{name:"greg"});
//接触对函数的引用
compareNames = null;
//7.2.1 闭包和变量
//作用域链的机制引出一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值.
//闭包保存的是整个变量对象,而不是某个特殊的变量
function createFunctions(){
var result = new Array();
for(var i=0;i<10;i++){
result[i] = function(){
return i;
};
}
return result;
} //每个都返回10
function createFunctions(){
var result = new Array();
for(var i=0;i<10;i++){
result[i]=function(num){
return num;
}(i);
};
return result;
}
createFunctions(); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//7.2.2 关于this对象
var name ="the Window";
var object = {
name :"My Object",
getNameFunc:function(){
return function(){
return this.name;
}
}
};
alert(object.getNameFunc()()) ; //"the window" (在非严格模式下)
//每次函数被调用时,都会自动获取两个特殊变量:this和arguments.内部函数在搜索整两个变量时,只会搜索到其活动对象位置.
//不过,把外部作用域中的this对象保存在一个闭包能够访问的变量里面,就可以让闭包访问该对象了
var name ="the Window";
var object = {
name :"My Object",
getNameFunc:function(){
var that=this;
return function(){
return that.name;
}
}
};
alert(object.getNameFunc()()) ; //"my Object" (在非严格模式下)
//
var name ="the Window";
var object = {
name :"My Object",
getNameFunc:function(){
return this.name;
}
};
object.getName(); //"My Object"
(object.getName)() ; //"My Object"
(object.getName = object.getName)(); //"the winodw" 在非严格模式下
//7.3内存泄露
//ie9之前,如果闭包的作用域中保存着一个HTML元素,那么就意味着钙元素将无法被销毁.
function assignHander(){
var element = document.getElementById("someElement");
element.onclick = function(){
alert(element.id);
}
}
//改写后可呗回收
function assignHander(){
var element = document.getElementById("someElement");
var id = element.id;
element.onclick = function(){
alert(id);
}
element= null;
}
//7,3 模仿块级作用域
function outputNumbers(count){
for (var i=0;i<count;i++){
alert(i);
}
alert(i); // Jishu
}
//无论在什么地方,只是临时需要一些变量,就可以使用私有作用域
function outputNumbers(count){
(function(){
for (var i=0;i<count;i++){
alert(i);
}
})();
alert(i); // 导致一个错误.
}
//建立私有作用域,避免命名冲突
(function(){
var now =new Date();
if (now.getMonth() == 0 && now.getDate() == 1){
alert("happy new year!!");
}
})();
//7.4 私有变量
</script>
</body>
</html>