欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談JS中的反柯里化( uncurrying)

 更新時(shí)間:2017年08月17日 09:26:15   作者:風(fēng)雨后見(jiàn)彩虹  
本篇文章主要介紹了淺談JS中的反柯里化( uncurrying),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

反柯里化

相反,反柯里化的作用在與擴(kuò)大函數(shù)的適用性,使本來(lái)作為特定對(duì)象所擁有的功能的函數(shù)可以被任意對(duì)象所用.

即把如下給定的函數(shù)簽名,

obj.func(arg1, arg2)

轉(zhuǎn)化成一個(gè)函數(shù)形式,簽名如下:

func(obj, arg1, arg2)

這就是 反柯里化的形式化描述。

例如,下面的一個(gè)簡(jiǎn)單實(shí)現(xiàn):

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

function sayHi () {
  return "Hello " + this.value +" "+[].slice.call(arguments);
}
var sayHiuncurrying=sayHi.uncurrying();
console.log(sayHiuncurrying({value:'world'},"hahaha"));

解釋:

  • uncurrying是定義在Function的prototype上的方法,因此對(duì)所有的函數(shù)都可以使用此方法。調(diào)用時(shí)候:sayHiuncurrying=sayHi.uncurrying(),所以u(píng)ncurrying中的 this 指向的是 sayHi 函數(shù); (一般原型方法中的 this 不是指向原型對(duì)象prototype,而是指向調(diào)用對(duì)象,在這里調(diào)用對(duì)象是另一個(gè)函數(shù),在javascript中函數(shù)也是對(duì)象)
  • call.apply(that, arguments) 把 that 設(shè)置為 call 方法的上下文,然后將 arguments 傳給 call方法,前文的例子,that 實(shí)際指向 sayHi,所以調(diào)用 sayHiuncurrying(arg1, arg2, ...) 相當(dāng)于 sayHi.call(arg1, arg2, ...);
  • sayHi.call(arg1, arg2, ...), call 函數(shù)把 arg1 當(dāng)做 sayHi的上下文,然后把 arg2,... 等剩下的參數(shù)傳給sayHi,因此最后相當(dāng)于 arg1.sayHi(arg2,...);
  • 因此,這相當(dāng)于 sayHiuncurrying(obj,args) 等于 obj.sayHi(args)。

最后,我們反過(guò)來(lái)看,其實(shí)反柯里化相當(dāng)于把原來(lái) sayHi(args) 的形式,轉(zhuǎn)換成了 sayHiuncurrying(obj,args),使得sayHi的使用范圍泛化了。 更抽象地表達(dá), uncurryinging反柯里化,使得原來(lái) x.y(z) 調(diào)用,可以轉(zhuǎn)成 y(x',z) 形式的調(diào)用 。 假設(shè)x' 為x或者其他對(duì)象,這就擴(kuò)大了函數(shù)的使用范圍。

通用反柯里化函數(shù)

上面例子中把uncurrying寫(xiě)進(jìn)了prototype,這不太好,我們其實(shí)可以把 uncurrying 單獨(dú)封裝成一個(gè)函數(shù);

var uncurrying= function (fn) {
  return function () {
    var args=[].slice.call(arguments,1);
    return fn.apply(arguments[0],args);    
  }  
};

上面這個(gè)函數(shù)很清晰直接。

使用時(shí) 調(diào)用 uncurrying 并傳入一個(gè)現(xiàn)有函數(shù) fn, 反柯里化函數(shù)會(huì)返回一個(gè)新函數(shù),該新函數(shù)接受的第一個(gè)實(shí)參將綁定為 fn 中 this的上下文,其他參數(shù)將傳遞給 fn 作為參數(shù)。

所以,對(duì)反柯里化更通俗的解釋可以是 函數(shù)的借用,是函數(shù)能夠接受處理其他對(duì)象,通過(guò)借用泛化、擴(kuò)大了函數(shù)的使用范圍。

所以 uncurrying更常見(jiàn)的用法是對(duì) Javascript 內(nèi)置的其他方法的 借調(diào) 而不用自己都去實(shí)現(xiàn)一遍。

文字描述比較繞,還是繼續(xù)看代碼:

var test="a,b,c";
console.log(test.split(","));

var split=uncurrying(String.prototype.split);  //[ 'a', 'b', 'c' ]
console.log(split(test,','));          //[ 'a', 'b', 'c' ]

split=uncurrying(String.prototype.split) 給 uncurrying 傳入一個(gè)具體的fn,即String.prototype.split ,split 函數(shù)就具有了 String.prototype.split 的功能,函數(shù)調(diào)用 split(test,',') 時(shí),傳入的第一個(gè)參數(shù)為 split 執(zhí)行的上下文,剩下的參數(shù)相當(dāng)于傳給原 String.prototype.split 函數(shù)。

再看一個(gè)例子:

var $ = {};
console.log($.push);             // undefined
var pushUncurrying = uncurrying(Array.prototype.push);
$.push = function (obj) {
  pushUncurrying(this,obj);
};
$.push('first');
console.log($.length);            // 1
console.log($[0]);              // first
console.log($.hasOwnProperty('length'));   // true

這里模仿了一個(gè)“類似jquery庫(kù)” 實(shí)現(xiàn)時(shí)借用 Array 的 push 方法。 我們知道對(duì)象是沒(méi)有 push 方法的,所以 console.log(obj.push) 返回 undefined,可以借用Array 來(lái)處理 push,由原生的數(shù)組方法(js引擎)來(lái)維護(hù) 偽數(shù)組對(duì)象的 length 屬性和數(shù)組成員。

同樣的道理,我們還可以繼續(xù)有:

var indexof=uncurrying(Array.prototype.indexOf);
$.indexOf = function (obj) {
  return indexof(this,obj);
};
$.push("second");
console.log($.indexOf('first'));       // 0
console.log($.indexOf('second'));       // 1
console.log($.indexOf('third'));       // -1

例如我們?cè)趯?shí)現(xiàn)自己的類庫(kù)時(shí),有些方法如果有些方法和原生的類似,那么可以通過(guò) uncurrying 借用原生方法。

我們還可以把 Function.prototype.call/apply 方法 uncurring,例如:

var call= uncurrying(Function.prototype.call);
var fn= function (str) {
  console.log(this.value+str);
};
var obj={value:"Foo "};
call(fn, obj,"Bar!");            // Foo Bar!

這樣可以非常靈活地把函數(shù)也當(dāng)做一個(gè)普通“數(shù)據(jù)”來(lái)使用,有函數(shù)式編程的趕腳,在一些類庫(kù)中經(jīng)常能看到這樣的用法。

通用 uncurrying 函數(shù)的進(jìn)擊

上面的 uncurrying 函數(shù)是比較符合思維習(xí)慣容易理解的版本,接下來(lái)一路進(jìn)擊,看幾個(gè)其他版本:

首先,如果B格高一點(diǎn),uncurrying 也可能寫(xiě)成這樣:

var uncurrying= function (fn) {
  return function () {
    var context=[].shift.call(arguments);
    return fn.apply(context,arguments);
  }
};

當(dāng)然如果還需要再提升B格,那么還可以是這樣:

var uncurrying= function (fn) {
  return function () {    
    return Function.prototype.call.apply(fn,arguments);
  }
};

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • nullJavascript中創(chuàng)建對(duì)象的五種方法實(shí)例

    nullJavascript中創(chuàng)建對(duì)象的五種方法實(shí)例

    今天上午,非常郁悶,有很多簡(jiǎn)單基礎(chǔ)的問(wèn)題搞得我有些迷茫,哎,代碼幾天不寫(xiě)就忘。目前又不當(dāng)COO,還是得用心記代碼哦!
    2013-05-05
  • IE autocomplete internet explorer''s autocomplete

    IE autocomplete internet explorer''s autocomplete

    IE autocomplete internet explorer''s autocomplete...
    2007-06-06
  • uniapp小程序項(xiàng)目獲取位置經(jīng)緯度信息

    uniapp小程序項(xiàng)目獲取位置經(jīng)緯度信息

    在實(shí)際項(xiàng)目中很多時(shí)候我們需要獲取設(shè)備的位置信息,去展示給客戶,或者以位置信息為參數(shù),繼續(xù)向服務(wù)器獲取一些數(shù)據(jù),這篇文章主要介紹了uni-app如何獲取位置信息(經(jīng)緯度),需要的朋友可以參考下
    2022-11-11
  • JS獲取Table中td值的方法

    JS獲取Table中td值的方法

    這篇文章主要介紹了JS獲取Table中td值的方法,實(shí)例分析了javascript操作table中td的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-03-03
  • 智能表格

    智能表格

    智能表格...
    2007-01-01
  • 詳解webpack3編譯兼容IE8的正確姿勢(shì)

    詳解webpack3編譯兼容IE8的正確姿勢(shì)

    這篇文章主要介紹了詳解webpack3編譯兼容IE8的正確姿勢(shì),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • JS實(shí)現(xiàn)下拉菜單賦值到文本框的方法

    JS實(shí)現(xiàn)下拉菜單賦值到文本框的方法

    這篇文章主要介紹了JS下拉菜單賦值到文本框的方法,涉及javascript頁(yè)面元素的選擇與賦值的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • 淺析js中的浮點(diǎn)型運(yùn)算問(wèn)題

    淺析js中的浮點(diǎn)型運(yùn)算問(wèn)題

    本篇文章主要是對(duì)js中浮點(diǎn)型運(yùn)算的問(wèn)題進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2014-01-01
  • JavaScript中二分查找的例題詳解

    JavaScript中二分查找的例題詳解

    二分查找在我們學(xué)習(xí)算法中是很重要的一部分,而且面試的時(shí)候會(huì)經(jīng)常的讓我們手寫(xiě)一些算法。所以這篇文章將通過(guò)三個(gè)場(chǎng)景帶大家深入了解二分查找算法
    2023-03-03
  • 在JavaScript中模擬類(class)及類的繼承關(guān)系

    在JavaScript中模擬類(class)及類的繼承關(guān)系

    眾所周知,JavaScript中沒(méi)有類,然而我們卻可以動(dòng)手實(shí)現(xiàn)一個(gè)擁有繼承特性的類,所以接下來(lái)我們要討論的便是在JavaScript中模擬類(class)及類的繼承關(guān)系:
    2016-05-05

最新評(píng)論