javascript - 關于apply()與call()的問題
問題描述
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()的在項目中應用價值是什么呢?
問題解答
回答1:樓上寫的真復雜:)
聽我講講,題主疑惑的地方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...
回答2:arguments是function內置屬性之一,表示函數數組對象,即 callSum1里的arguments 指代 num1和num2https://developer.mozilla.org...
apply 跟 call的價值在于,能夠使得指定函數里面的this指向特定的對象上,舉個例子,我們用document.querySelectorAll()獲取的dom其實是一個類數組對象,非數組,如果想要用數組的方法時,可以是這樣
var doms = document.querySelectorAll(’p’);[].forEach.call(doms, function(e){ //遍歷元素});
而apply 跟call主要區別在于參數格式,這個建議題主翻翻MDN。
回答3: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比較好理解 就是改變 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
實現偏函數 Partial Function跟數學上的偏函數類似,比如:
函數 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 只能想到這些了。。。。
回答4:手動設置this作用域。
回答5:百度一下你就知道。
相關文章:
1. objective-c - ios百度地圖定位問題2. html - css 如何添加這種邊框?3. javascript - js 有什么優雅的辦法實現在同時打開的兩個標簽頁間相互通信?4. javascript - 關于定時器 與 防止連續點擊 問題5. javascript - 求助關于js正則問題6. javascript - node.js服務端渲染解疑7. javascript - 求助這種功能有什么好點的插件?8. html5 - rudy編譯sass的時候有中文報錯9. 為何 localStorage、sessionStorage 屬于html5的范疇,但是為何 IE8卻支持?10. 微信開放平臺 - Android調用微信分享不顯示
