第五章 引用类型>Function类型
Function类型
每个函数都是Function类型的实例,与其他引用类型一样具有属性和方法。
函数声明语法定义:
function sum(num1, num2) { return num1+num2; }
函数表达式定义:
var sum = function(num1, num2) { return num1 + num2; };
由于函数是对象,因此函数名是一个指向函数对象的指针。不会与某个函数绑定。
function sum(num1, num2) { return num1 + num2; } console.log(sum(10, 10)); //20 var anotherSum = sum; //将函数的值赋给anotherSum,不带圆括号的函数名访问的是函数指针而非调用函数。 console.log(anotherSum(10, 10)); //sum和anotherSum指向同一个函数 //20 sum = null; //就算把sum清空; anotherSum还是可以调用, 清空的只是函数名的指针而已,ahotherSum的指针没有被清空 console.log(anotherSum(10, 10));
//20
函数没有重载
同名函数只能存在一个,后面覆盖前面的;
funcition addSomeNumber(num) { return num+100; } function addSomeNumber(num) { return num + 200; } var result = addSomeNumber(100); console.log(result); //300 //上面的代码和下面的基本没有区别 var addSomeNumber = function(num) { return num +100; }; var addSomeNumber = function(num) { return num +200; };
函数声明与函数表达式
函数声明: 解析器率先读书函数声明。函数声明被提升到代码的顶部,使在执行任何代码之前可用。
console.log(sum (10, 10)); function sum (num1, num2) { return num1 + num2; } // 20 对代码求值时JS引擎再第一遍声明函数并将他们放到源代码的顶部。
函数表达式: 只有变量名被提前了, 而变量名知识一个指向函数对象的一个指针。函数体和函数声明依然在变量所在行执行。
console.log(sum1(10, 10)); var sum1 = function(num1, num2) { return num1 + num2; }; // Uncaught TypeError: sum1 is not a function(…) //在执行到函数所在的语句之前,变量sum并没有保存对函数的引用.变量被提升到了顶部,赋值语句还在原来的地方进行。第一行代码就会导致 Uncaught TypeError;根本不会执行到下一行
作为值的函数
function callSomeFunction(someFunction, someArguments) { return someFunction(someArguments); } function getGreeting(name) { return "hello!" + name; } var result2 = callSomeFunction(getGreeting, "zhangsan"); // 没有使用圆括号的getGreeting,只是获得了getGreeting指向的那个函数对象的指针,并不是立即调用函数,返回结果。
console.log(result2); // hello!zhangsan
从一个函数中返回另外一个函数。
function createComparisonFunction(propertyName) { return function (object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if(value1 < value2) { return -1; } else if (value1 > value2) { return 1; }else { return 0; } }; } var data = [{name: "Zachary", age: 28},{name: "Nicholas", age: 29}]; //创建一个包含2个对象的数组data。每个对象都有一个name属性,和age属性
data.sort(createComparisonFunction("name"));
//调用写好的排序函数,把name属性当做排序函数的参数传递进去 console.log(data[0].name); data.sort(createComparisonFunction("age")); console.log(data[0].name); // Nicholas // Zachary
函数内部属性
函数内部俩个特殊的对象:
arguments: 类数组对象,包含着传入函数中的所有参数。
aruguments还有一个callee的属性;
callee: 该属性是个指针,指向拥有这个arguments对象的函数。
function factorial(num) { if(num<=1) { return 1; } else { return num*arguments.callee(num-1); } } var trueFactorial = factorial; factorial = function() { return 0;};
//factorial的指针被修改
console.log(factorial(5));
// 0
console.log(trueFactorial(5));
//120 trueFactorial的指针依然指向的是之前的阶乘函数对象。
this: 引用的是函数 据以执行的环境对象,或者也可以说是this值(在网页的全局作用域调用this对象引用的是WINDOW);
window.color = "red"; var o = { color: "blue" }; function sayColor() { console.log(this.color); // 由于函数是全局作用域定义的函数,this.color = window.color } sayColor(); o.sayColor = sayColor; //相当于用匿名函数的形式把函数赋给变量,sayColor 里面的this引用对象的是o o.sayColor(); // red // blue
caller:保存这调用当前函数的函数的引用;如果是全局作用域调用调用当前函数,值为null;
function outer() { inner(); } function inner(){ console.log(inner.caller); //可以用arguments.callee.caller。是一样的效果 } outer(); // outer() { inner(); }
函数的属性和方法
length: 函数希望接受的命名参数的个数;
prototype: 保存所有实例和方法的真正所在。
函数包含2个非继承来的方法:apply()和call(),作用是在特定作用域中调用函数,设置函数体内的this对象的值。
apply(): 接受俩个参数, 第一个参数是再其运行函数的作用域,第二个参数,可以是数组,也可以是Array的实例,也可要是arugments的对象。
function sum2(num1, num2) { return num1 + num2; } function callSum1(num1, num2) { return sum2.apply(this, arguments); //截获sum2函数并当做返回值返回
//这里 的this指的window。因为sum2是全局作用域的函数 this = window.sum2
} function callSum2(num1, num2) { return sum2.apply(this,[num1, num2]); } console.log(callSum1(10, 10)); console.log(callSum2(10, 10)); // 20 // 20
call():和apply的作用一样。第二个接受的参数方式不同, 递给call()的参数必须逐个列举出来。
function sum(num1, num2) { return num1 + num2; } function callSum(num1, num2) { return sum.call(this, num1, num2); } console.log(callSum(10, 10));
call()和apply()最大的作用扩充函数赖以运行的作用域
window.color = "red"; var o = { color: "blue" }; function sayColor() { console.log(this.color); } sayColor(); sayColor.call(this); sayColor.call(window); sayColor.call(o); // red // red // red // blue
bind(): 这个方法会创建一个函数实例,this值 会被绑定到传给bind()函数的值。
window.color = "red"; var o = { color: "blue" }; function sayColor() { console.log(this.color); } var objectSayColor = sayColor.bind(o); //把this的值设置为o objectSayColor(); // blue