日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

javascript - 求助關(guān)于call和apply的問題,反柯里化

瀏覽:278日期:2022-12-15 15:57:36

問題描述

下面是uncurring的兩種實現(xiàn)

實現(xiàn)1

Function.prototype.uncurrying = function(){ var self = this; return function(){// 獲取傳入的上下文對象var context = Array.prototype.shift.call(arguments);// 這里的this是調(diào)用uncurrying者return self.apply(context, arguments); };};var push = Array.prototype.push.uncurrying ();var arr = [];push(arr, 1); // ==> arr = [1]push(arr, 4); // ==> arr = [1, 4]

實現(xiàn)2

Function.prototype.uncurrying = function(){ var self = this; return function(){return Function.prototype.call.apply(self, arguments); };};var push = Array.prototype.push.uncurrying ();var arr = [];push(arr, 1); // ==> arr = [1]push(arr, 4); // ==> arr = [1, 4]

兩種結(jié)果是一樣的,但是第二種實現(xiàn)的方式我有點迷糊,主要是這里

第一種方式顯示的用self,在這里也就是push方法執(zhí)行了一下, self.apply(context, arguments);但是如下第二種實現(xiàn)方式,卻沒有發(fā)現(xiàn)self執(zhí)行的痕跡,按我的理解這里就是用apply修改call的上下文為self,這里也就是push,但這樣有執(zhí)行push方法嗎?難道call內(nèi)部的實現(xiàn)幫忙執(zhí)行了self?求解 Function.prototype.call.apply(self, arguments);

瞬間被你點通,謝謝 !

louiszhai

Function.prototype.call.apply(self, arguments);先用apply修改了call的上下文為self,后續(xù)調(diào)用uncurrying,相當(dāng)于在self上調(diào)用call方法,也就執(zhí)行了self

問題解答

回答1:

Function.prototype.call.apply(self, arguments);這個看起來有些繞,其實很好理解。實際上,由你的第二種實現(xiàn)還可以推出反柯里化的第三種實現(xiàn)

Function.prototype.unCurrying = function () { return this.call.bind(this);};var push = Array.prototype.push.unCurrying(), obj = {};push(obj, ’123’, ’456’);console.log(obj); //Object {0: '123', 1: '456', length: 2}

接下來我會先分析下你的第二種實現(xiàn),再分析第三種實現(xiàn)。你的實現(xiàn)是這樣的:

Function.prototype.uncurrying = function(){ var self = this; return function(){return Function.prototype.call.apply(self, arguments); };};var push = Array.prototype.push.uncurrying();

誰調(diào)用uncurrying,誰就等于this或self. 這意味著self就是數(shù)組的push方法.替換掉self,最終外部的push等同如下函數(shù):

function(){ return Function.prototype.call.apply(Array.prototype.push, arguments);};

函數(shù)放在這里,我們先來理解apply函數(shù),apply有分解數(shù)組為一個個參數(shù)的作用。

推導(dǎo)公式:a.apply(b, arguments) 意味著把b當(dāng)做this上下文,相當(dāng)于是在b上調(diào)用a方法,并且傳入所有的參數(shù),如果b中本身就含有a方法,那么就相當(dāng)于 b.a(arg1, arg2,…)

公式1:a.apply(b, arguments) === b.a(arg1, arg2,…)

由于call 和 apply 除參數(shù)處理不一致之外,其他作用一致,那么公式可以進一步演化得到:

公式2:a.call(b, arg) === b.a(arg)

公式1這些代入上面的函數(shù),有:

a = Function.prototype.call 即a等于call方法。

我們接著代入公式,有:

b = Array.prototype.push 即b等于數(shù)組的push方法

那么 Function.prototype.call.apply(Array.prototype.push, arguments)就相對于:

Array.prototype.push.call(arg1, arg2,…),那么:

push([], 1) 就相當(dāng)于 Array.prototype.push.call([], 1),再代入公式2,相當(dāng)于:

[].push(1)

答案已經(jīng)呼之欲出了,就是往數(shù)組中末尾添加數(shù)字1。

接下來我來分析反柯里化的第三種實現(xiàn):

對于this.call.bind(this);部分,this相當(dāng)于Array.prototype.push,那么整體等同于如下:

Array.prototype.push.call.bind(Array.prototype.push)

這里的難點在于bind方法,bind的實現(xiàn)比較簡單,如下:

Function.prototype.bind = function(thisArg){ var _this = this; var _arg = _slice.call(arguments,1); return function(){ var arg = _slice.call(arguments); arg = _arg.concat(arg); return _this.apply(thisArg,arg); }}

想要理解必須化繁為簡,理解得越簡單,也就理解得越透徹。進一步簡化bind的原理,等同于誰調(diào)用bind,就返回一個新的function。

我們假設(shè)函數(shù)fn調(diào)用bind方法如fn.bind([1, 2]),經(jīng)過簡化,忽略bind綁定參數(shù)的部分,最終返回如下:

function(){ return fn.apply([1, 2], arguments);}

以上,將fn替換為 Array.prototype.push.call,[1, 2]替換為 Array.prototype.push,那么:

Array.prototype.push.call.bind(Array.prototype.push) 將等同于:

function(){ return Array.prototype.push.call.apply(Array.prototype.push, arguments);}

這個看起來和反柯里化的第二種實現(xiàn)有些不大相同,不要急,雖然表面上看起來不一致,但骨子里還是一致的。請耐心往下看:

不同的地方在于前半部分 Array.prototype.push.call,這里它是一個整體,實際上想代表的就是call方法。而我們都知道,所有函數(shù)的call方法,最終都是Function.prototype 的 call方法。那么,就有如下恒等式成立:

Array.prototype.push.call === Function.prototype.call //true

那么以上函數(shù)將等同于:

function(){ return Function.prototype.call.apply(Array.prototype.push, arguments);}

褪去代入的參數(shù),函數(shù)可還原為:

function(){ return Function.prototype.call.apply(self, arguments);}

綜上,最終反柯里化的第三種實現(xiàn)將和第二種實現(xiàn)完全一致,推理完畢,碼字不易,喜歡的請點個贊謝謝~

為了加深對bind 和 柯里化的理解,我還專門撰寫了博客深入分析它們。

請參看 函數(shù)式編程之柯里化與反柯里化 、Function.prototype.bind方法指南 。

喜歡的同學(xué)還可以關(guān)注我的專欄路易斯前端深度課

回答2:

基礎(chǔ)call和apply的區(qū)別和作用不再贅述

call和apply源碼實現(xiàn)他們很接近,這里只介紹call,舉個例子:a.call(b, c)

取出第一個參數(shù)x = b || {}

x.fn = a

拼接除第一個參數(shù)以外的參數(shù),用逗號分隔,結(jié)果為d

創(chuàng)建獨立執(zhí)行環(huán)境的函數(shù)e = new Function(),函數(shù)內(nèi)部執(zhí)行x.fn(d)

執(zhí)行創(chuàng)建的e

方案二的理解這里就不考慮call和apply擴大對象方法的問題,因為從源碼中方法都會動態(tài)創(chuàng)建,以下就不再贅述這個問題。

Function.prototype.call.apply(self, arguments);var push = Array.prototype.push.uncurrying ();

self指向Array.prototype.push

(Function.prototype.call).apply(Array.prototype.push, arguments);

利用剛講解的源碼,把2變形,得出:Array.prototype.push.(Function.prototype.call)(arguments),這里還需要轉(zhuǎn)化,call接受的不是數(shù)組,見4。

arguments是類數(shù)組對象[arr, 1],把3變形,得出:Array.prototype.push.(Function.prototype.call)(arr, 1)

call的源碼已經(jīng)解釋過,于是變化4,得出arr.(Array.prototype.push)(1)

寫得好看一點,arr.push(1)

標(biāo)簽: JavaScript
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本久久成人网| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 日本在线不卡视频| 欧美搞黄网站| 91精品一区国产高清在线gif| 福利一区二区三区视频在线观看| 欧美国产专区| 欧美激情在线精品一区二区三区| 国产欧美日韩精品高清二区综合区 | а√在线中文在线新版| 麻豆国产精品视频| 精品久久亚洲| 国产劲爆久久| 高清一区二区三区av| www在线观看黄色| 亚洲天堂1区| 欧美成人国产| 视频一区在线播放| 亚洲精品免费观看| 欧美亚洲tv| 精品一区二区三区免费看| 久久精品国产网站| 日韩精品诱惑一区?区三区| 91精品亚洲| 日韩中文欧美在线| 日韩精品午夜视频| 精品黄色一级片| 日韩欧美一区二区三区在线观看 | 久久人人97超碰国产公开结果| 久久精品av| 水蜜桃久久夜色精品一区的特点 | 夜久久久久久| 亚洲视频二区| 日韩av在线免费观看不卡| 国产精品免费不| 性欧美videohd高精| 一区在线免费| 欧美一区二区三区久久| 91欧美日韩| 亚洲一区黄色| 国产精品久久久亚洲一区| 在线看片福利| 日本欧洲一区二区| 国产激情精品一区二区三区| xxxxx性欧美特大| 亚洲免费中文| 欧美精品aa| 91精品国产调教在线观看| 亚洲欧美日韩精品一区二区 | 国产欧美日韩精品高清二区综合区 | 国产精品视频一区视频二区| 国产资源在线观看入口av| 99在线精品视频在线观看| 欧美亚洲二区| 精品一区免费| 国产精品多人| 米奇777超碰欧美日韩亚洲| 日韩精品一区二区三区中文在线| 久久精品免费看| av亚洲在线观看| 国产精品极品国产中出| 国产伊人精品| 国产精品美女午夜爽爽| 午夜精品影院| 国产一区二区三区亚洲综合| 男人操女人的视频在线观看欧美| 久久久精品区| 日韩精品一区第一页| 激情黄产视频在线免费观看| 日韩1区2区3区| 久久久久一区| 欧美亚洲国产日韩| 欧美精品黄色| 高清一区二区三区av| 综合欧美亚洲| 亚洲福利精品| 美女精品一区二区| 亚洲一二av| 日韩精品久久久久久久电影99爱| 欧美日韩精品一区二区三区视频 | 日本天堂一区| 国产综合亚洲精品一区二| 国产探花一区| 日韩制服丝袜av| 久久激情中文| 久久精品天堂| 国产三级一区| 蜜芽一区二区三区| 激情视频一区二区三区| 视频在线不卡免费观看| 国产亚洲第一伦理第一区| 视频一区二区三区中文字幕| 欧美日韩尤物久久| 国产欧美日韩免费观看| 亚洲精品综合| 国产亚洲毛片| 久久亚洲精品中文字幕蜜潮电影| 麻豆久久久久久久| 欧美一区二区三区免费看| 男女性色大片免费观看一区二区 | 欧美在线看片| 三级欧美在线一区| 亚洲深夜视频| 狠狠久久伊人| 欧美aa在线视频| 国产精品久久久久久久久久妞妞| 日韩激情精品| 日韩区一区二| 亚洲日产av中文字幕| 亚洲视频www| 黄色亚洲精品| 欧美成人精品| 午夜影院欧美| 伊人成人在线视频| jiujiure精品视频播放| 1024精品一区二区三区| 亚洲四虎影院| 日韩av在线中文字幕| 久久精品理论片| 国内揄拍国内精品久久| 精品三级av在线导航| 精品资源在线| 丰满少妇一区| av最新在线| 免费在线小视频| 久久久精品久久久久久96 | 国产99精品一区| 久久高清精品| 91成人网在线观看| 999在线观看精品免费不卡网站| 成人自拍av| 999视频精品| 欧美日韩国产亚洲一区| 99riav1国产精品视频| 视频在线观看91| 婷婷精品在线| 欧美视频久久| 国产精品.xx视频.xxtv| 里番精品3d一二三区| 国产videos久久| 久久精品国语| 久久不射网站| 日韩欧美2区| 欧美成人一二区| 综合日韩av| 亚洲一级影院| 日本欧美在线看| 国产精品一区二区精品 | 国产精品66| 亚洲天堂av影院| 欧美特黄一区| 亚州国产精品| 蜜桃久久久久| 欧洲av一区二区| 另类av一区二区| 无码日韩精品一区二区免费| 国产精品v日韩精品v欧美精品网站 | 亚洲一区欧美| 国产欧美自拍| 国模大尺度视频一区二区| 欧美成人a交片免费看| 好吊一区二区三区| 欧美一级一区| 97精品国产| 亚洲免费观看| 欧美一区网站| 久久成人福利| 91精品国产91久久久久久黑人| 国产精品毛片在线| 国产精品最新| 久久网站免费观看| 日韩精品一区二区三区中文在线 | 色婷婷久久久| 性欧美长视频| 国产精品一级| 91精品综合| 91国内精品| 亚洲成人精品| 日韩国产成人精品| 欧美三区四区| 亚洲精品三级| 麻豆成全视频免费观看在线看| 亚洲激精日韩激精欧美精品| 午夜电影一区| 久久久久九九精品影院| 激情综合在线| 欧美日韩伊人| 99视频精品视频高清免费| 在线精品一区| 国产99在线| 婷婷久久免费视频| av亚洲一区二区三区| 亚洲伊人精品酒店| 日韩国产一区二区| 日韩美女国产精品| 久久久久久久久99精品大| 欧美日韩一区自拍| 99国产成+人+综合+亚洲欧美| 精品深夜福利视频| 亚洲免费毛片|