函式屬性和方法
我們大家都知道,一個函式它有屬性和方法,每個函式都包含兩個屬性: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”。
好處 使用這兩個方法擴充作用域最大的好處在於,物件不需要與方法有任何耦合關係。