8.1 函数定义:
变量声明提前,但是变量赋值并不会提前
函数声明语句不能出现在循环,条件判断或者try/catch/finally以及with语句中:
8.2 函数调用(函数调用,方法调用,构造函数调用,间接调用(call,apply))
1、var isStrict = (function() { return !this; }());
2、this的指向问题(嵌套函数this的指向问题)
可以解决的方法有:var self = this 或者使用 apply
//嵌套函数 var o = { m: function () { var self = this; //将this的值保存在一个变量中 console.log(this === o); f(); function f() { console.log(this === o); //false this的值是全局对象或undefined console.log(self === o); //true } } }; o.m();
8.3 函数的实参与形参
1、可选参数
function getPropertyNames(o, /* optional */ a) { if (a === undefined) a = []; for (var property in o) a.push(property); return a; } var a = getPropertyNames(o); getPropertyNames(p, a);
可以使用a = a || [] 来代替上面的if语句,但是a必须是预先声明的,因为a是作为参数传入的,即相当于var a;所以这里也可以这么使用
2、可变长的实参列表,实参对象arguments,它是一个类数组对象
实参对象的属性:length/callee/caller
function max(/* ... */) { //最小值 var max = Number.NEGATIVE_INFINITY; for (var i = 0; i < arguments.length; i++) if (arguments[i] > max) max = arguments[i]; return max; } var largest = max(1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6); // => 10000
在非严格模式下,对实参对象arguments对象进行操作会影响到传入的参数,如删除其中一个元素或是改变length属性等都会影响到参数
严格模式下,对caller或是callee进行读写操作都会产生一个类型错误:
callee:指代当前正在执行的函数
calller:指代调用当前正在执行的函数的函数
3、将对象属性用作实参
参数的顺序问题:
//这里需要记住参数顺序 function arraycopy(/* array */ from, /* index */ from_start, /* array */ to, /* index */ to_start, /* integer */ length) { //code goes here } //这个版本效率低,但是不用记住参数顺序 function easycopy(args) { arraycopy(args.from, args.from_start || 0, // Note default value provided args.to, args.to_start || 0, args.length); } // Here is how you might invoke easycopy(): var a = [1, 2, 3, 4], b = []; easycopy({from: a, to: b, length: 4});
4、实参类型
传入参数时,先检测传入的参数
function sum(a) { if (isArrayLike(a)) { //这个函数在第七章 var total = 0; for (var i = 0; i < a.length; i++) { var element = a[i]; if (element == null) continue; if (isFinite(element)) total += element; else throw new Error("sum(): elements must be finite numbers"); } return total; } else throw new Error("sum(): argument must be array-like"); } //尽可能的在抛出异常之前将非数字转换为数字 function flexisum(a) { var total = 0; for (var i = 0; i < arguments.length; i++) { var element = arguments[i], n; if (element == null) continue; if (isArray(element)) n = flexisum.apply(this, element); else if (typeof element === "function") n = Number(element()); else n = Number(element); if (isNaN(n)) throw Error("flexisum(): can‘t convert " + element + " to number"); total += n; } return total; }
8.4 作为值的函数
时间: 2024-10-09 20:51:52