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));
alert(callSum2(10,10));
//call()例子就省略了
問:
1.sum.apply(this,arguments)說的是物件sum呼叫apply方法,this指的是callSum()與sum()都是同一個作用域運行,arguments指的就是”sum1,sum2”?
2.apply()與call()的在專案中應用價值是什麼?
淡淡烟草味2017-07-05 11:03:57
樓上寫的真複雜:)
聽我講,題主疑惑的地方
1:
function callSum1(num1,num2) {
return sum.apply(this,arguments); // 这里的arguments和下面的[num1,num2]是同一个意思
}
function callSum2(num1,num2) {
return sum.apply(this,[num1,num2]);
}
arguments 是一個類似陣列的物件, 對應於傳遞給函數的參數。 arguments物件是所有函數中可用的局部變數。你可以使用arguments物件在函數中引用函數的參數。
PS:this的指向在函數定義的時候是確定不了的,只有函數執行的時候才能確定this到底指向誰,實際上this的最終指向的是那個調用它的對象
2、call和apply應用價值(存在的意義):
作用都是為了改變函數運行時的上下文而存在。 即改變函數體內部this的指向
"說白點,a有xx方法,b沒有。b可以問a借!"(這tm不就是繼承嘛~)
call和apply不同點:
接受參數方式不一樣。
如下:
call接受的是連續參數,apply接受的是陣列參數。
A.call(this, a,b,c,d)
A.apply(this, [a,b,c,d])
一個傳送門:http://www.jianshu.com/p/a7b1...
typecho2017-07-05 11:03:57
arguments是function內建屬性之一,表示函數數組對象,即 callSum1裡的arguments 指涉 num1和num2
https://developer.mozilla.org...
apply 跟call的價值在於,能夠使得指定函數裡面的this指向特定的對像上,舉個例子,我們用document.querySelectorAll()
獲取的dom其實是一個類數組對象,非數組,如果想要用陣列的方法時,可以是這樣
var doms = document.querySelectorAll('p');
[].forEach.call(doms, function(e){
//遍历元素
});
而apply 跟call主要區別在於參數格式,這個建議題主翻翻MDN。
巴扎黑2017-07-05 11:03:57
1.sum.apply(this,arguments)說的是物件sum呼叫apply方法,this指的是callSum()與sum()都是同一個作用域運行,arguments指的就是」sum1,sum2」?
2.apply()與call()的在專案中應用價值是什麼?
針對 1 執行結果兩個都回傳 20
20
sum.apply(this,arguments)
指的是用apply來呼叫sum 指定sum執行的時候的this為現在的這個this 後面的arguments是參數列表是一個類別數組對象,你可以簡單地當成數組對待。
sum.apply(this,[num1, num2])
與上方類似。
關於arguments,發一張截圖你可能就會有感性的認識了
以下是針對第二點的回答
比較好理解 就是改變 this 指向在 ajax 請求的 success 回呼的時候
例如在vue開發的時候 如果沒有箭頭函數 得要用 var that = this
這樣暫存 this。 如果可以欽點this就沒這些問題
舉個栗子
function sayName(){
console.log(this.name);
}
var xiao_ming = {
name: '小明妹妹'
}
// 钦点 this
sayName.call(xiao_ming);
arguments 透過類別數組物件的形式 保存著函數的參數列表 。
function sumAll(){
var argu = Array.prototype.slice.call(arguments);
// 从 0 开始积、每次 sum + cur 作为下次的 sum
return argu.reduce((sum, cur) => sum + cur, 0);
}
其實從這裡可以窺見:執行 slice 只需要物件具備 length
正確的下標
就可以正常執行 並回傳結果。
因為數組的許多方法都可以用在類別數組物件上,因此類別數組物件很多時候確實可以被認為就是數組。
// 声明一个类数组对象
var a = {
0: 'hello',
1: 'seg',
2: 'ment',
3: 'fault',
length: 4
}
// forEach
Array.prototype.forEach.call(a, elem => console.log(elem));
// => 遍历打印
// reduce
var helloSF = Array.prototype.reduce.call(a, (acc, cur) => acc + cur + ' ', '');
console.log(helloSF);
// =>
// "hello seg ment fault "
還可以做的更像陣列
var a = {
0: 'hello',
1: 'seg',
2: 'ment',
3: 'fault',
length: 4
}
a.__proto__ = Array.prototype;
a.forEach(e => console.log(e));
Array.prototype.reduce.call(a, (acc, cur) => acc + cur + ' ', '');
Object Really Like Array
跟數學上的偏函數類似,例如:
函數f(x, y) = x + y
如果令y = k
那麼可以得到偏函數f(x, k) = x + k
( 或者這樣可能更好理解: f (x, 4) = x + 4
)
一般都是用 bind 來實現偏函數的。 不過 apply 和 call 和 bind 應該要集中的講講。
function logger(type){
return console.log.bind(console, type);
}
用 apply 實現上述 logger
就是:
function logger2(type){
return function(){
var argu = Array.prototype.slice.call(arguments);
argu.unshift(type);
console.log.apply(console, argu);
}
}
高階函數一般指的是返回值是函數或其參數是函數的函數。
setTimeout
是個很好的例子 它接受一個參數(一般是函數) 然後在一定時延後執行它。
不過傳進去之後一般 this 就指向了 全域物件 window 如果想要欽點 this 就得用 call apply 和 bind
上面的 logger2 就做到了這點 回傳了一個函數出去
關於柯里化 先看函數 add
function add(x, y){
return a + b;
}
add(1, 2);
// =>
// 3
如果參數能一個一個的傳 傳到第二個的時候就得到結果:
var add1 = add(1);
add1(2);
// => 3
add(3)(4);
// => 7
第一次執行回傳了一個函數,如果把add 看成是數學意義上的函數那就是f(x, y) = x + y
我們執行了一次add(1)
得到add1
其實就是令x = 1
了,於是得到偏函數
f(1, y) = 1 + y
第二次再執行 y 會得到實際值 算式就可以算出結果出來。
這其實是一步步消元的過程。
有什麼用的?
我在函數式程式設計方面也才初學,還沒領會到精髓,唯一對柯里化體會的用處是惰性求值
剛剛的運算在參數給齊之前不會運行等到參數夠了就會算出結果。
大半夜不睡覺刷sf 只能想到這些了。 。 。 。