JavaScript的Function类型

ECMAScript中的函数是对象,与其他引用类型一样具有属性和方法。因此,函数名实际是一个指向函数对象的指针。

函数声明

function sum(num1,num2){    
    return num1+num2;
}//函数声明

var sum = function(num1,num2){  
    return num1+num2;
};     //函数表达式 这里的分号很重要

没有重载

function addSomeNumber(num){    
    return num + 100;
}

function addSomeNumber(num){    
    return num + 200;
}

var result = addSomeNumber(100);  //300

创建第二个函数时覆盖了引用第一个函数的变量addSomeNumber。

函数声明与函数表达式

alert (sum(10,10));
function sum(num1,num2){    
    return num1+num2;
}

这样的代码可以正常执行。代码开始执行前,解析器会率先读取函数声明并将其添加到执行环境中,对代码求值前,JS引擎在第一遍会声明函数并将它们放到源代码树的顶部。但改为函数表达式就会出错。

作为值的函数

  • 像传递参数一样把一个函数传递给另一个函数
function callSomeFunction(someFunction,someArgument){   
    return someFunction(someArgument);
}

function add10(num){
    return num+10;
}

var result1 = callSomeFunction(add10,10);
alert(result1);  //20

function getGreeting(name){
    return "Hello"+name;
}
var result2 = callSomeFunction(getGreeting,"Mike");
alert(result2);  //Hello Mike

//callSomeFunction是通用的,函数作为第一个参数传递进去,返回执行第一个参数后的结果
  • 从一个函数中返回另一个函数
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 date = [{name:"Mike", age:28},{name:"Amy", age:29}];//创建包含两个对象的数组
date.sort(creatComparisonFunction("name"));
alert(date[0].name);//Amy
date.sort(creatComparisonFunction("age"));
alert(date[0].name);//Mike

函数内部属性

  • arguments:保存函数参数的类数组对象
  • arguments.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函数已经变为简单的返回0的函数
alert(trueFactorial(5));  //120
alert(factorial(5)); //0
  • this对象
window.color = "red";
var o ={color: "blue" };

function sayColor(){
    alert(this.color);
}
sayColor(); //"red" 全局作用域调用时 this.color求值转换为window.color求值
o.sayColor = sayColor; //函数对象赋给o
o.sayColor(); //"blue"  this.color转换为o.color

注:函数名仅是一个包含指针的变量,即使在不同执行环境,全局sayColor()函数与o.sayColor()指向的是同一个函数。

  • caller对象
function outer(){   
    inner();
}
function inner(){   
    alert(arguments.callee.caller);
}
outer();

我们来看一个例子

function func1(num){
                if(num==1){
                    return num;
                }else{
                    return num*func1(num-1);
                }
            }

            var func=func1; //由于这里是赋值操作,所以调用func时会找这个式子之前的func1,到func1内部时,调用下面func1

            func1 = function  (){  //函数表达式声明
                return 1;
            };

            alert(func(3));  //3
  • 当第二次声明换成函数声明时,结果为1。因为解析器有一个函数声明提升的过程。
  • 当第一次声明func1,返回值写为return num * arguments.callee(num-1);,结果为6。这是因为消除了耦合现象。

函数属性和方法

  • length属性 表示函数希望接收的命名参数的个数
function sayName(name){
    alert(name);
}
function sum(num1,num2){    
    return num1 + num2;
}
function sayHi(){
    alert("hi");
}
alert(sayName.length);//1
alert(sum.length);//2
alert(sayHi.length);//0
  • apply()和call()方法:在特定的作用域中调用函数
    apply():一个参数是在其中运行函数的作用域,另一个是参数数组(可是Array实例,也可以是Arguments对象)。
    call(): 第一个参数this值没有变化,只是其余参数需要逐个列举。
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]);//传入数组
}
function callSum3(num1,num2){
    return sum.call(this,num1,num2);//call()接收参数的方式不同
}
alert(callSum1(10,10));  //20
alert(callSum2(10,10));  //20
alert(callSum3(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
  • bind()方法:会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
window.color = "red";
var o = {color: "blue"};
function sayColor(){
    alert(this.color);
}
var objectSayColor = sayColor.bind(o);//sayColor()调用bind()并传入对象o,创建objectSayColor()函数,objectSayColor()函数this值变为o
objectSayColor();   //blue

猜你喜欢

转载自blog.csdn.net/gaoshanyangzhi_1999/article/details/81200070
今日推荐