@cpt
2015-04-20T03:25:08.000000Z
字数 2029
阅读 925
读书笔记
//以函数声明定义,不会抛出错误
sayHi();
function sayHi(){
alert('Hi');
}
//以函数表达式定义,出错
sayHi();
var sayHi = function(){
alert('Hi');
}
/*再来看一个例子
*理解两者区别
*/
//以下代码表面上看会在condition为true时返回一个sayHi函数的定义;否则就使用另外一个定义。但是,这是无效语法,JS引擎会尝试修正错误。各浏览器对修正错误的办法不一致。
if(condition){
function sayHi(){
alert('Hi');
}
}else{
function sayHi(){
alert('yoooo');
}
}
//可以这样使用
var sayHi();
if(condition){
sayHi = function(){
alert('Hi');
}
}else{
sayHi = function(){
alert('yooo');
}
}
function factorial(){
if(num<=1){
return 1;
}else{
return num*factorial(num-1);
}
}
//但是以下代码会让它出错,因为在JS中,函数名只是一个包含指向某个函数的指针的变量。当被设置为空时,指向原是函数的引用只有anotherFactorial,接下来调用anotherFactorial()时,由于必须执行factorial(),而factorial已经不再是函数,导致错误。即使用arguments.callee替换掉else中的factorial,在严格模式下仍会出错。(arguments.callee是一个指向正在执行函数的指针)
var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));
//正确用法是使用命名函数表达式
var factorial = (function f(num){
if( num <= 1){
return 1;
}else{
return num * f(num-1);
}
});
//创建一个名为f()的命名函数表达式,然后将他它赋值给变量factorial,这样即便把函数赋值给另外一个变量,函数名字f仍然有效,递归仍能正确完成。
关于JS闭包的问题,下周另外做一个专门的笔记。
var name = "The window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFun()());//"The window"非严格模式下
getNameFunc返回一个函数,所以调用object.getNameFunc()()就会立即调用它返回的匿名函数,结果就是返回一个字符串。在这里返回"The window".为什么匿名函数没有其包含作用域即外部作用域中的this对象呢?
因为每个函数在调用的时候都会取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止(这里为window,因为i额匿名函数的执行对象为window),因此永远不可能直接访问外部函数中的这两个变量。不过,把外部作用域中的this对象保存到一个闭包能够访问的变量里,就可以让闭包访问该对象了。
var name = "The window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this; //that===object
return function(){
return that.name;
};
}
};
alert(object.getNameFun()());
//arguments也存在同样的问题,如果想要访问作用域中的arguments对象,必须将该对象的引用保存在另一个闭包能够访问的变量中
在JavaScript中,函数表达式是一种非常有用的技术。使用函数表达式无需对函数命名,从而实现动态编程。