程序员

函数属性和方法

2018-07-22  本文已影响0人  WANG_M

我们大家都知道,一个函数它有属性和方法,每个函数都包含两个属性:length和prototype。

length属性

length属性表示函数希望接收的命名参数的个数。
举个例子

function sayName(name){
       alert(name);
}
function sum(sum1,sum2){
       return num1 +  num2;
}
function sayHi(){
       alert("hi");
}
alert(sayName.length);  //1
alert(sum.length);      //2
alert(sayHi.length);    //0

上述代码中,我定义了三个函数,三个函数所带参数的个数不同,因此length属性值也各不相同。

prototype

prototype属性是保存它们所有实例方法的真正所在,也就是说,toString()和valueOf()等方法实际上都保存在prototype之下,只不过是通过各自对象的实例来进行访问的。
每个函数都包含两个非继承而来的方法:apply()和call()。
相同之处:都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
区别 两个方法仅在于接收函数的方式不同。
apply()
1.apply()方法接收两个参数:一个是其中运行函数的作用域,另一个是参数数组。
2.参数可以是Array的实例,也可以是arguments对象。

function sum(num1,num2){
    return num1 + num2;
}
function callSum1(num1,num2){
    return sum.apply(this,arguments);
}
function callSum2(num1,num2){
    return sum.apply(this,[num1,num2]);
}
alert(callSum1(10,10));  //20
alert(callSum2(10,10));  //20

在这个例子中
callSum1()在执行sum()函数时传入this作为this值(因为是在全局作用域中作用的,所以传入是window对象)和arguments对象。
callSum2()同时也调用了sum()函数,但是它传入的是this和一个参数数组。
这两个函数都会正常执行并返回正确结果。
call()

function sum(num1,num2){
    return num1 + num2;
}
function callSum(num1,num2){
    return sum.call(this,num1,num2);  //参数逐个列举
}
alert(callSum(10,10));     //20

在使用call()方法时,callSum()必须明确出入每一个参数。

事实上,传递参数并不是这两个方法真正的用武之地;它们强大的地方在于能够扩充函数赖以运行的作用域。

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

sayColor()是一个全局变量。在全局作用域中调用它时,会显示“red”,因为此时的this就是window。
但是当运行sayColor.call(o)时,函数的执行环境发生了变化,此时的this指向了o,于是结果变成了“blue”。

好处 使用这两个方法扩充作用域最大的好处在于,对象不需要与方法有任何耦合关系。

上一篇下一篇

猜你喜欢

热点阅读