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

您的位置:首頁技術文章
文章詳情頁

javascript - 求助關于call和apply的問題,反柯里化

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

問題描述

下面是uncurring的兩種實現

實現1

Function.prototype.uncurrying = function(){ var self = this; return function(){// 獲取傳入的上下文對象var context = Array.prototype.shift.call(arguments);// 這里的this是調用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]

實現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]

兩種結果是一樣的,但是第二種實現的方式我有點迷糊,主要是這里

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

瞬間被你點通,謝謝 !

louiszhai

Function.prototype.call.apply(self, arguments);先用apply修改了call的上下文為self,后續調用uncurrying,相當于在self上調用call方法,也就執行了self

問題解答

回答1:

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

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}

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

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

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

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

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

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

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

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

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

公式1這些代入上面的函數,有:

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

我們接著代入公式,有:

b = Array.prototype.push 即b等于數組的push方法

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

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

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

[].push(1)

答案已經呼之欲出了,就是往數組中末尾添加數字1。

接下來我來分析反柯里化的第三種實現:

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

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

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

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的原理,等同于誰調用bind,就返回一個新的function。

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

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);}

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

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

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

那么以上函數將等同于:

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

褪去代入的參數,函數可還原為:

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

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

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

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

喜歡的同學還可以關注我的專欄路易斯前端深度課

回答2:

基礎call和apply的區別和作用不再贅述

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

取出第一個參數x = b || {}

x.fn = a

拼接除第一個參數以外的參數,用逗號分隔,結果為d

創建獨立執行環境的函數e = new Function(),函數內部執行x.fn(d)

執行創建的e

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

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),這里還需要轉化,call接受的不是數組,見4。

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

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

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

標簽: JavaScript
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品毛片视频| 国户精品久久久久久久久久久不卡| 国产精品亚洲综合在线观看| 日韩电影免费网址| 国产欧美一区二区三区精品观看| 国产精品一区二区三区av麻| 久久国产日本精品| 亚洲最大av| 9色精品在线| 国产 日韩 欧美 综合 一区| 国产精品一区二区三区四区在线观看| 99国产精品私拍| 少妇精品导航| 欧美aa在线视频| 久久久精品五月天| 久久激情五月婷婷| 综合一区av| 精品1区2区3区4区| а√天堂中文在线资源8| 亚洲精品极品| 国产欧美二区| 精品日韩在线| 免费在线亚洲| 久久精品天堂| 国产精品女主播一区二区三区| 久久国产精品色av免费看| 9999国产精品| 婷婷成人基地| 在线看片一区| 欧美性感美女一区二区| 日本不卡高清| 卡一卡二国产精品| 快she精品国产999| 秋霞国产精品| 日韩av中文字幕一区二区三区| 国产精品久久乐| 国产精品极品| av中文字幕在线观看第一页| 蜜桃一区二区三区在线观看| 六月丁香综合在线视频| 国产精品99免费看| 国产欧美在线| 日本国产亚洲| 国产精品久久久久久久久久妞妞 | 久久精品国产一区二区| 久久网站免费观看| 丁香婷婷久久| 精品一区二区三区中文字幕| 欧美日韩国产免费观看| japanese国产精品| 国产精品99免费看| 国产精品毛片一区二区三区| 免费不卡在线视频| 国产精品色婷婷在线观看| 亚洲精品中文字幕乱码| 日韩欧美久久| 精品国产亚洲日本| 六月天综合网| 日本高清不卡一区二区三区视频| 欧美99久久| 久久精品免费看| 亚洲欧美久久久| 欧美特黄一区| 成人在线网站| 美日韩一区二区三区| 欧美综合另类| 波多视频一区| 精品久久网站| 亚洲aa在线| 久久中文精品| 国产精东传媒成人av电影| 99riav1国产精品视频| 国产成人精选| 成人黄色av| 91日韩欧美| 日韩在线观看| 日本久久成人网| 99精品国产一区二区三区| а√天堂8资源在线| 国产日韩精品视频一区二区三区| 亚洲精品国产偷自在线观看| 国产日产一区| 国产精品片aa在线观看 | 久久中文字幕一区二区三区| 婷婷成人在线| 综合激情婷婷| 久久精品99久久久| 国产精品国码视频| 精品视频久久| 九九色在线视频| 日本亚洲欧洲无免费码在线| 日韩精品免费一区二区三区| 日本欧美韩国一区三区| 模特精品在线| 亚洲狼人精品一区二区三区| 91亚洲自偷观看高清| 一级欧美视频| 国产欧美日韩一区二区三区四区 | 欧美精品一区二区三区精品| 国产一区二区三区探花| 国产精品久久久久9999高清| 日韩三区四区| 国产一区二区三区四区| 99久久www免费| 波多野结衣久久精品| 免费不卡在线观看| 麻豆91精品91久久久的内涵| 欧美日韩精品一区二区三区在线观看| 老司机免费视频一区二区三区| 成人午夜网址| 石原莉奈一区二区三区在线观看| 日韩高清在线观看一区二区| 婷婷久久免费视频| 久久精品三级| 国产精品sm| 国产视频一区在线观看一区免费| 一区二区国产精品| 超碰成人av| 日韩福利在线观看| 国产激情久久| 亚洲少妇自拍| 精品1区2区3区4区| 综合日韩av| 国产精品激情电影| 蜜桃视频在线观看一区二区| 日韩高清不卡在线| 婷婷色综合网| 午夜国产精品视频免费体验区| 国产精品va| 日韩1区2区3区| 噜噜噜躁狠狠躁狠狠精品视频| 欧美激情视频一区二区三区免费 | 日本成人手机在线| 99久久精品国产亚洲精品| 欧美日韩国产传媒| 精品久久在线| 欧美亚洲一级| 在线精品亚洲| 日韩在线观看不卡| 久久国产精品美女| 日本va欧美va瓶| 欧美成人综合| 国产精选在线| 国产视频网站一区二区三区| 国产欧美日韩| 亚洲精品日本| 欧美日韩伊人| 亚洲精品美女91| 蜜桃av一区二区| 青青草国产成人99久久| 日韩一区二区三区在线看| 亚洲综合五月| 国产va免费精品观看精品视频| 欧美在线精品一区| 国产精品久av福利在线观看| 一区二区精彩视频| 国产日产精品_国产精品毛片| 亚洲ab电影| 九九九精品视频| 欧美va天堂在线| 日韩精品电影一区亚洲| 久久国际精品| 国产一区二区三区四区大秀 | 麻豆成人91精品二区三区| 老鸭窝一区二区久久精品| 捆绑调教美女网站视频一区| 激情综合自拍| 99国产精品久久久久久久| 久久亚洲国产| 亚洲91网站| 伊人久久在线| 亚洲少妇自拍| 欧美精品成人| 久久精品国产大片免费观看| 免费日韩一区二区三区| av日韩中文| 日韩有码av| zzzwww在线看片免费| 日韩高清在线一区| 在线日韩欧美| 久久免费视频66| 免费精品视频在线| 精精国产xxxx视频在线播放| 蜜桃视频一区二区| 国产66精品| 国产亚洲精品美女久久久久久久久久| 精品国产亚洲日本| 日日摸夜夜添夜夜添国产精品| 蜜桃一区二区三区在线观看| 久久精品99国产精品日本| 91tv亚洲精品香蕉国产一区| 99国产精品久久久久久久成人热 | 男人天堂欧美日韩| 99国内精品| а√天堂中文在线资源8| 视频一区二区国产| 亚洲五月婷婷| 波多视频一区| 久久久久美女| 91看片一区|