函数也是对象,拥有属性和方法,就类似普通对象那样。
1,length属性
arguments.lenght 表示传入实参的个数。
函数的length属性时只读属性,代表形参的个数。可以用arguments.callee.length表示:
function check(args){ var actual = args.length; var expected = args.callee.length; if(actual != expected){ throw Error(`Expected ${expected} ,args got ${actual}`) } } function f(x,y,z){ check(arguments); return x+y+z; } f(1,2)
2.call()和apply()方法
可以将call()和apply()看做是某个对象的方法,里面的第一个实参是要调用函数的母对象,即上下文,在函数体内是通过this来获得对它的引用。例如:
f.call(o)
f.apply(o)
对象o来调用函数f();
f.call(o,1,2)
f.apply(o,[1,2])
call和apply类似的功能,唯一不同就是传入实参的形式,call是单个传,apply是以数组的形式传入。
3,bind()方法
var g = f.bind(o);
将函数f绑定到o上面,可以通过g(x)来调用o.f(x);
4,toString方法
foo.toString() "function foo(x,y){ return x+y; }" Date.toString() "function Date() { [native code] }"
5,构造函数
var f = new Function('x','y','return x+y;')
Function()构造函数可以传入任意数量的字符串实参,最后一个实参所代表的文本就是函数体。
6,可调用的对象
Window.alert()
Document.getElementById()
RegExp对象
本质上不是Function对象,
这里:检测一个对象是不是函数,最好检测它的class属性
Object.prototype.toString.call(foo)
"[object Function]"
7,函数式编程
map()和reduce()来实现一个数组的平均值和标准差
var data = [1,2,3,4,5]; var sum = function(x,y){return x+y}; var squarte = function(x){return x*x}; var mean = data.reduce(sum,0)/data.length; var deviations = data.map(function(v){return v - mean}); var stddev = Math.sqrt(deviations.map(squarte).reduce(sum,0)/data.length) mean 3 stddev 1.4142135623730951
如果一味的用for循环,那么就不是函数式编程了,reduce(cb,originItem)。
8,高阶函数
即操作函数的函数。它接收一个或者多个函数作为参数,并返回 一个新函数。
function not(f){ return function(){ var result = f.apply(this,arguments); console.log("this",this) return !result; } } var even = function(x){ return x%2 === 0; } var odd = not(even); [1,1,3,5,5].every(odd);
还有一个更常见的例子:f(g())
function compost(f,g){ return function(){ return f.call(this,g.apply(this,arguments)); } }