属性
函数是一种特殊的对象,它有固定的属性(length, prototype)和方法,也可以自定义属性。
// 自定义属性
a.counter=0;
function a() {
a.counter ++ ;
}
length
function check(args) {
var actual = args.length;
var expected = args.callee.length;
if(actual !== expected) {
throw Error("Expected :" + expected + ";But got " + actual);
}
}
prototype
原型对象,每一个函数都包含不同的原型对象,当将函数作为构造函数时,新创建的对象会从原型对象上继承属性。
call()和apply()方法
函数可以看作是特殊的对象,而call()和apply()则是该对象的方法。其实就是“方法的方法”。它们一般的应用场景为:作为实参传入时的调用。如:
function f (a) {
a.call();
}
二者类似,主要的区别在于传入的实参形式不同:call()
实参都单独作为参数,'apply()`则将实参放到一个数组中去:
a.call(o, 1, 2);
a.apply(o, [1, 2)];
bind()方法
bind()方法是在ECMAScript5中新增的方法,它可以被非常简单的实现。它不仅仅是将函数绑定到一个对象,还附带其他的一些作为:除了第一个实参,传入的bind()的实参也会绑定到this, 这个附带效果是一种常见的函数式编程技术,也称为“柯里化”。
function f(x) { return this.x + y };
var o = {x: 2};
var g = f.bind(o);
g(3); // => 5
toString()方法
大多数的toString()方法返回函数的完整源码,内置函数往往返回 一个类似“[native code]”的字符串。
用Function()来构造函数
用Function()来构造函数,相当于在全局作用域中执行的eval(), 可以在自己的私有作用域内定义新变量和函数,用的非常少。
var f = new Function("x", "y", "return x*y;"}
var f = function(x, y) { return x*y; }
上面两个函数定义的几乎等价,主要差别:
-
非常重要的一点:
Function()
所创建的函数并不是使用词法的作用域,而是会在全局作用域(顶层函数)中编译它。 -
Function()
可以在JavaScript在运行时动态地创建并编译(和eval类似) - 每次调用
Function()
都会解析函数体,并创建新的函数对象。