最近水群的時候看見了一個題目:
add(2)(3)(4);
簡單了說就是鏈式呼叫,鏈式呼叫的方法有很多,jQuery的,underscore的和lodash這三個庫採用了不同的方式。而上面這個就簡單多了:
function add(x) {
var sum = x;
var tmp = function (y) {
sum = sum + y;
return tmp;
};
tmp.toString = function () {
return sum;
};
return tmp;
}
複製程式碼
這邊只是使用了輸出或者是運算的時候型別的轉換。
JavaScript中幾乎所有的物件都繼承了toString和valueOf這兩個方法:
valueOf()會把資料型別轉換成原始型別
toString()會把資料型別轉換成string型別
需要注意的是,這兩個方法在不同使用場景會有不同的優先順序:
正常情況下,優先呼叫toString()
有運算操作符的情況下valueOf()的優先順序高於toString()
當呼叫valueOf()方法無法運算後還是會再呼叫toString()方法
我們可以改寫這兩個方法測試優先順序:
var n = {
toString: function () {
return 1
},
valueOf: function () {
return 2
}
}
var obj = {1: 1, 2: 2};
console.log(+n);//1
console.log(obj[n]);//2
複製程式碼
除了上面三個方法之外,還是有一些會比較特殊,比如Date,應該還有很多我還不知道的優先順序:
var date=new Date();
date.valueOf = function(){
return '1000'
}
console.log(+date);
複製程式碼
大概知道這兩個方法之後,迴歸這個函式:
function add(x) {
var sum = x;
var tmp = function (y) {
sum = sum + y;
return tmp;
};
tmp.toString = function () {
return sum;
};
return tmp;
}
複製程式碼
呼叫:add(5)(3)(2)
其實add(5)是一個函式
console.log(typeof add(5));//function
是這個函式:
function (y) {
sum = sum + y;
return tmp;
};
複製程式碼
因為閉包的原因,tmp和sum都被存起來了。所以我們可以鏈式呼叫。
add(5)(2)(3);
當我們執行完畢,想要運算或者是輸出的時候,就會執行toString方法。
tmp.toString = function () {
console.log('toString')
return sum;
};
複製程式碼
然後執行輸出或者是運算:
add(5)(2) + add(5)(3);//toString toString
但是不同瀏覽器會有不同的結果,火狐上面:
console.log(add(5)(4));
不進行運算是不會呼叫toString的。Coding 個人筆記