function类型:
1.函数初认识
函数实际上是一个对象,对象就和其他引用类型一样,具有属性和方法。由于函数是一个对象,所以函数名是一个指向函数对象的指针,不会与某个函数绑定。
var sum = function(num1, num2){
return num1 + num2;
};
在使用函数表达式时,没有必要使用函数名,通过变量sum就可以引用函数,注意末尾有分号。
还有一种是使用构造函数,Function,接收任意数量参数,但最后一个是函数体。
var sum = new Function("num1", "num2", "return num1 + num2"); // 不推荐
不过这种写法对于理解函数是对象,函数名是指针比较好。
因此,函数没有重载概念。
2. 两种函数定义方式
解析器在想执行环境中加载数据时,对函数声明和函数表达式的操作不一样。解析器会先读取函数声明,使得它在执行任何代码前可用,这个过程叫函数声明提升。函数表达式则会等到执行到它是才会被解释执行。
3.函数内部属性:
函数内部,有两个特殊对象:arguments和this。arguments是一个类数组对象,包含传入函数的所有参数,它的主要作用是保存函数,但他有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数,
例如:定义一个阶乘函数:
/*阶乘函数*/
function factorial (n) {
if (n === 1) {
return 1;
}
// return n * factorial(n-1);
return n * arguments.callee(n-1);
}
var result = factorial(4);
console.log(result);
优点:无论引用函数时使用的是啥名字,都可以保证正常完成函数递归调用。
关于this:this引用的是函数据已执行的环境对象,也可以说是this值,当在网页的全局作用域中调用函数时,this对象引用的就是window。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;//给o增加一个方法,
o.sayColor(); //"blue",此时this指向O这个对象。
在函数调用之前,this的值并不确定,因此this可能会在代码执行过程中引用不同的对象,
与callee一起的还有一个caller,该属性返回的是调用该函数的函数。
注意一点,在严格模式下,callee会报错;不能为caller属性赋值。
4. 函数属性和方法:
每个函数包含两个属性:length和prototype
length表示希望接收参数的个数。
对于所有的引用类型,prototype是保存他们所有实例方法的所在。换句话说,诸如toString()和valueOf()等方法实际上都保存在prototype名下,只不过是通过各自对象的实例访问罢了。在创建自定义引用类型以及实现继承时,prototype属性的作用极为重要,在ES5中,prototype属性是不可枚举的,因此使用for-in无法发现。
每个函数包含两个方法:apply() 和call()
这两个方法的用途都是在特定的作用于在调用函数,实际上就是设置函数体内this对象的值。首先apply() 方法接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组。第二个参数与可以使Array实例,也可以是arguments对象。
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); // 传入 arguments 对象
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); // 传入数组
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20
传递参数并不是他们的主要用途,他们的强大之处在于扩充函数赖以运行的作用域。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
当调用sayColor.call(o) 时,函数的执行环境不一样了,,此时函数体内部的this指向了O,于是结果显示为blue。
使用他们的好处是,对象不需要与方法有任何耦合关系,二可以直接调用方法。
ES5中还定义了一个方法: bind() ,这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值:
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
在这里,sayColor()调用bind()方法,传入对象O,创建了objectSayColor()函数,objectSayColor()函数的this值等于O,因此在全局作用域中调用这个函数,也会看到blue。
5.基本包装类型:
为了便宜操作基本类型值,ES5引入了3个特殊的引用类型:Boolen Number String 。
var s1 = "some text";
var s2 = s1.substring(2);