JavaScript的Function类型

ECMAScript的函数是对象,函数名是指针数组

建立:浏览器

函数声明法:安全

   
   
            
   
   
  1. function sum (num1, num2) {  
  2.     return num1 + num2;  

函数表达式法:app

  
  
           
  
  
  1. var sum = function(num1, num2) {  
  2.     return num1 + num2;  
  3. }; 

函数表达式法:这种不推荐,由于这种语法会致使解析两次代码(第一次解析常规ECMAScript代码,第二次解析传入构造函数中的字符串),从而影响性能ide

  
  
           
  
  
  1. var sum = new Function("num1""num2""return num1 + num2");   //不推荐 

同时使用函数声明和函数表达式:这种语法会在Safari出错函数

  
  
           
  
  
  1. var sum = function sum () {} 

因为函数名只是指针,因此以下:性能

 

  
  
           
  
  
  1. function sum(num1, num2){  
  2.     return num1 + num2;  
  3. }          
  4. alert(sum(10,10));         //20  
  5.           
  6. var anotherSum = sum;          
  7. alert(anotherSum(10,10));  //20  
  8.           
  9. sum = null;          
  10. alert(anotherSum(10,10));  //20 

函数名是指针,因此没有重载:this

 

  
  
           
  
  
  1. function addSomeNumber (num) {  
  2.     return num + 100;  
  3. }  
  4.  
  5. function addSomeNumber (num) {  
  6.     retrun num + 200;  
  7. }  
  8.  
  9. var result = addSomeNumber(100); //300 

上面代码其实是:spa

  
  
           
  
  
  1. function addSomeNumber (num) {  
  2.     return num + 100;  
  3. }  
  4.  
  5. addSomeNumber = function (num) {  
  6.     retrun num + 200;  
  7. }  
  8.  
  9. var result = addSomeNumber(100); //300 

建立第二个函数时,改变了addSomeNumber的指向prototype

函数声明与函数表达式的一个区别:

解析器会率先读取函数声明,并使其在执行任何代码前可用;而函数表达式,必须等到解析器执行到所在行,才能被解释执行

  
  
           
  
  
  1. alert(sum(10,10));              //20  
  2.       
  3. function sum(num1, num2){  
  4.     return num1 + num2;  

若是改为以下,就会报错

  
  
           
  
  
  1. alert(sum(10,10));              //causes an error  
  2.       
  3. var sum = function(num1, num2){  
  4.     return num1 + num2;  
  5. };  

把函数当值使用:

将一个函数做为另外一个函数的结果返回

  
  
           
  
  
  1. function callSomeFunction(someFunction, someArgument){  
  2.     return someFunction(someArgument);  
  3. }  
  4.  
  5. function add10(num){  
  6.     return num + 10;  
  7. }  
  8.           
  9. var result1 = callSomeFunction(add10, 10);  
  10. alert(result1);   //20  
  11.           
  12. function getGreeting(name){  
  13.     return "Hello, " + name;  
  14. }  
  15.           
  16. var result2 = callSomeFunction(getGreeting, "Nicholas");  
  17. alert(result2);   //Hello, Nicholas 

从一个函数中返回另外一个函数,如给对象数组排序:(默认状况下,sort()会调用toString()方法)

  
  
           
  
  
  1. function createComparisonFunction(propertyName) {  
  2.           
  3.     return function(object1, object2){  
  4.         var value1 = object1[propertyName];  
  5.         var value2 = object2[propertyName];  
  6.           
  7.         if (value1 < value2){  
  8.             return -1;  
  9.         } else if (value1 > value2){  
  10.             return 1;  
  11.         } else {  
  12.             return 0;  
  13.         }  
  14.     };  
  15. }  
  16.  
  17. var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];  
  18.           
  19. data.sort(createComparisonFunction("name"));  
  20. alert(data[0].name);  //Nicholas  
  21.           
  22. data.sort(createComparisonFunction("age"));  
  23. alert(data[0].name);  //Zachary   

函数内部属性:

函数内部有两个特点的对象 arguments 和 this

arguments:是一个类数组对象,包含传入函数的全部参数

callee:是arguments的属性,该属性是一个指针,指向拥有这个arguments对象的函数

下面是一个经典的阶乘例子:

  
  
           
  
  
  1. function factorial(num){  
  2.     if (num <= 1) {  
  3.         return 1;  
  4.     } else {  
  5.         return num * arguments.callee(num-1)  
  6.     }  
  7. }  
  8.  
  9. var trueFactorial = factorial;  
  10.           
  11. factorial = function(){  
  12.     return 0;  
  13. };  
  14.           
  15. alert(trueFactorial(5));   //120  
  16. alert(factorial(5));   //0 

this:引用的是函数据以执行的环境对象(当在网页的全局做用域中调用函数时,this对象引用的就是window)

  
  
           
  
  
  1. window.color = "red";  
  2. var o = { color: "blue" };  
  3.           
  4. function sayColor(){  
  5.     alert(this.color);  
  6. }  
  7.           
  8. sayColor();     //red  
  9.           
  10. o.sayColor = sayColor;  
  11. o.sayColor();   //blue 

caller:这个属性中保存着调用当前函数的函数的引用,若是在全局做用域中调用当前函数,它的值为null(Opera9.6版以前不支持该属性)

  
  
           
  
  
  1. function outer(){  
  2.     inner();  
  3. }  
  4.           
  5. function inner(){  
  6.     alert(inner.caller);  
  7. }  
  8.           
  9. outer();              //function outer(){  
  10.                       //    inner();  
  11.                       //} 

下面这种写法与上面同理,只是达到了更好的松耦合,这样函数名称能够变更而不用改变内部代码

  
  
           
  
  
  1. function outer(){  
  2.     inner();  
  3. }  
  4.           
  5. function inner(){  
  6.     alert(arguments.callee.caller);  
  7. }  
  8.           
  9. outer();              //function outer(){  
  10.                       //    inner();  
  11.                       //} 

注意:

1.这严格模式下,访问 arguments.callee 会致使错误。

2.ECMAScript5 还定义了 arguments.caller 属性,但在严格模式下也会致使错误,而在非严格模式下这个属性始终是undefined。定义这个属性是为了分清 arguments.caller 和 函数的caller属性。以上都是为了增强这门语言的安全性,这样第三方代码就不会在相同的环境里窥视其余代码了。

3.在严格模式下,不能给函数的caller属性赋值,不然会出错。

函数属性和方法:

因为在ECMAScript中,函数是对象,因此函数有属性和方法

length:表示函数但愿接收的命名参数的个数

  
  
           
  
  
  1. function sayName(name){  
  2.     alert(name);  
  3. }        
  4.           
  5. function sum(num1, num2){  
  6.     return num1 + num2;  
  7. }  
  8.           
  9. function sayHi(){  
  10.     alert("hi");  
  11. }  
  12.           
  13. alert(sayName.length);  //1  
  14. alert(sum.length);      //2  
  15. alert(sayHi.length);    //0 

prototype:第6章

apply():用途是在特定的做用域中调用函数,实际上等于设置函数体内this对象的值

需传入2个参数:该运行函数的做用域(this)、参数数组

  
  
           
  
  
  1. function sum(num1, num2){  
  2.     return num1 + num2;  
  3. }  
  4.           
  5. function callSum1(num1, num2){  
  6.     return sum.apply(this, arguments);  //因为在全局做用域中调用的,因此this指的是window对象  
  7. }  
  8.           
  9. function callSum2(num1, num2){  
  10.     return sum.apply(this, [num1, num2]);  
  11. }  
  12.           
  13. alert(callSum1(10,10));   //20  
  14. alert(callSum2(10,10));   //20 

注意:在严格模式下,未指定环境对象而调用函数,则this值不会转型为window。除非明确把函数添加到某个对象 或者 调用apply()或call(),不然this值将是undefined

call():用途是在特定的做用域中调用函数

传入参数:该运行函数的做用域(this)、逐一列出参数

  
  
           
  
  
  1. function sum(num1, num2){  
  2.     return num1 + num2;  
  3. }  
  4.           
  5. function callSum(num1, num2){  
  6.     return sum.call(this, num1, num2);  
  7. }  
  8.           
  9. alert(callSum(10,10));   //20 

apply()和call()真正的用武之地是扩充函数赖以运行的做用域,以下:

  
  
           
  
  
  1. window.color = "red";  
  2. var o = { color: "blue" };  
  3.           
  4. function sayColor(){  
  5.     alert(this.color);  
  6. }  
  7.           
  8. sayColor();             //red  
  9.           
  10. sayColor.call(this);    //red  
  11. sayColor.call(window);  //red  
  12. sayColor.call(o);       //blue 

使用apply()或call()来扩充做用域的最大的好处,就是对象不须要与方法有任何耦合关系(这跟以前那个版本比(讲this时),省下不少多余的步骤)

bind():把this值与该函数绑定

  
  
           
  
  
  1. window.color = "red";  
  2. var o = { color: "blue" };  
  3.                              
  4. function sayColor(){  
  5.     alert(this.color);  
  6. }  
  7. var objectSayColor = sayColor.bind(o);  
  8. objectSayColor();      //blue 

把o与objectSayColor的this绑定,因此调用时返回的是blue,而不是red,第22章

支持bind()的浏览器有IE9+、Firefox 4+、Chrome……

每一个函数继承的toLocaleString()、toString()、valueOf()都返回的函数的代码,因浏览器而异。

相关文章
相关标签/搜索