1. 程式人生 > >函式屬性和方法

函式屬性和方法

我們大家都知道,一個函式它有屬性和方法,每個函式都包含兩個屬性: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”。

好處 使用這兩個方法擴充作用域最大的好處在於,物件不需要與方法有任何耦合關係。