频道栏目
首页 > 资讯 > HTML/CSS > 正文

引用类型之Function类型

17-01-07        来源:[db:作者]  
收藏   我要投稿

引用类型之Function类型:函数就是对象,函数名是指针。每一个函数都是Function类型的实例,而且和其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。

函数声明与函数表达式

解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其执行代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。因此,除了什么时候可以通过变量访问函数这一点区别外,函数声明与函数表达式的语法其实是等价的。

//使用函数声明,可以正常执行。首先读取并将函数声明添加到执行环境中
alert(sum(10,20));
function sum(num1,num2){
    return num1+num2;
}

//使用函数表达式不能正确执行,因为函数还没有加载
alert(sum(10,20));
var sum=function (num1,num2){
    return num1+num2;
}

函数没有重载

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

function sum(num1){
    return num1;
}
//比没有执行第一个函数,而是执行了第二个函数。所以函数没有重载。
//理解函数名是指针,第二个函数覆盖了第一个,指针执行了另一个地址。
alert(sum(20,30)); //20

作为返回值的函数

由于ECMAScript中的函数名本身就是变量,因此函数也可以作为值来使用。即可以作为参数或者返回值。

//接收两个参数,第一个参数是一个函数,第二个应该是要传递给该函数的一个值
function callSomeFunction(someFunction,someArgument){
    return someFunction(someArgument);
}

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

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

function getGreeting(name){
    return "Hello,"+name;
}

var result2=callSomeFunction(getGreeting,"Tom");
alert(result2);

我们可以从一个函数中返回另一个函数,即闭包。

//通过根据不同的属性,返回不同的比较函数
function createComparisonFunction(propertyName){
    return function(object1,object2){
        var value1=object1[propertyName];
        var value2=object2[propertyName];
        if(value1value2){
            return 1;
        }else{
            return 0;
        }
    }
}

var data=[{name:"Tom",age:25},{name:"Jerry",age:30}];
data.sort(createComparisonFunction("name"));
alert(data[0].name);//Jerry
data.sort(createComparisonFunction("age"));
alert(data[0].name);//Tom

函数内部属性

在函数内部,有两个特殊的对象:arguments和this。arguments的主要用途是保存函数中所有参数,这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。

//使用arguments.callee替代函数名,消除耦合
function factorial(num){
    if(num<=1){
        return 1;
    }else{
        return num*arguments.callee(num-1);
    }
}

alert(factorial(5));

this引用的是函数据以执行的环境对象——或者也可以说是this值(当在网页的全局作用域中调用函数时,this对象引用的就是window)

var color="red";
var o={color:"blue"};
function sayColor(){
    alert(this.color);
}

sayColor(); //red

//函数据以执行的环境对象
o.sayColor=sayColor;
o.sayColor(); //blue

ECMAScript 5也规范化了另一个函数对象的属性:caller。这个属性保存着调用当前函数的函数的引用,如果是在全局域中调用当前函数,它的值为null。

function outer(){
    inner(); 
}
function inner(){
    alert(arguments.callee);
    alert(inner.caller);
}
/**
 * 调用输出的是
 * alert(arguments.callee);
 *callee 指向当前的函数
 *  function inner(){
        alert(arguments.callee);
        alert(inner.caller);
    }
 *  
    alert(inner.caller);
    caller指向调用当前函数的函数
 *   function outer(){
            inner();
        }
 */
outer();

函数的属性和方法

每个函数都包含两个属性:length和prototype。其中,length表示函数希望接收的命名参数的个数;
每个函数都包含两个非继承而来的方法:apply()和call()。这两个方法都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
apply()方法接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组。其中,第二个参数可以是Array的实例,也可以是arguments对象。

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

function callSum1(num1,num2){
    //运行函数的作用域:在这里指callSum1
    //传入arguments对象
    return sum.apply(this,arguments);
}
function callSum2(num1,num2){
    //传入数组
    return sum.apply(this,[num1,num2]);
}
alert(callSum1(10,19));
alert(callSum1(10,19));

call()方法与apply()方法的作用相同,他们的区别仅在于接收参数的方式不同。对于call()方法而言,第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。即,在使用call()方法时,传递给函数的参数必须逐个列举出来。传递参数并非apply()和call()真正用武之地,它们真正强大的地方是能够扩充函数赖以运行的作用域。对象和方法不需要任何的耦合关系

var color="red";
var o={color:"blue"};

function sayColor(){
    alert(this.color);
}
//在o作用于上执行,对象和方法不需要任何的耦合关系
sayColor.call(o);
相关TAG标签
上一篇:javaMail邮件工厂接收类
下一篇:打包后的IE使用方法
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站