<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法_javascript技巧

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 20:54:58
        文檔

        讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法_javascript技巧

        讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法_javascript技巧:但是我后來也跟人說,因為接受的參數(shù)太多,所以如果不把智能提示寫得很清楚的話,連我自己都常常搞不清楚該怎么用。 不過,接受參數(shù)多,除了容易弄錯用法以外,還會產(chǎn)生另一個問題,這也是我編寫出今天發(fā)布的這個東西的原因。 來看一下JS版的頁碼呈現(xiàn)組件的完
        推薦度:
        導(dǎo)讀讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法_javascript技巧:但是我后來也跟人說,因為接受的參數(shù)太多,所以如果不把智能提示寫得很清楚的話,連我自己都常常搞不清楚該怎么用。 不過,接受參數(shù)多,除了容易弄錯用法以外,還會產(chǎn)生另一個問題,這也是我編寫出今天發(fā)布的這個東西的原因。 來看一下JS版的頁碼呈現(xiàn)組件的完

        但是我后來也跟人說,因為接受的參數(shù)太多,所以如果不把智能提示寫得很清楚的話,連我自己都常常搞不清楚該怎么用。

        不過,接受參數(shù)多,除了容易弄錯用法以外,還會產(chǎn)生另一個問題,這也是我編寫出今天發(fā)布的這個東西的原因。
        來看一下JS版的頁碼呈現(xiàn)組件的完全版函數(shù)簽名:
        代碼如下:
        function pnView(
        currentPage, actionCurrent,
        beginPage, endPage,
        actionBegin, actionEnd,
        currentSiblings, actionCurrentSibling,
        preventFolding, actionFolding,
        endOfBegin, beginOfEnd,
        actionBeginSibling, actionEndSibling
        )

        可以看到,這個可以最大幅度進(jìn)行自定義的完全版函數(shù)簽名,接受14個參數(shù),而其中有一半——也就是7個參數(shù),是要接受回調(diào)函數(shù)的。
        由此產(chǎn)生的問題就是需要手工寫入多次的“function(){}”等字符組合,就像這樣:
        代碼如下:
        function ww(s) { document.write(s); }
        function ws(n) { ww(' (' + n + ') '); }
        pnView(14, function (n) { ww(' [' + n + '] ') },
        1, 27,
        function (n) { ww('|< ' + n + ' '); }, function (n) { ww(' ' + n + ' >|'); },
        2, ws,
        1, function () { ww(' ... '); },
        2, 2,
        ws, ws
        );

        當(dāng)我在網(wǎng)頁中測試這個組件的時候我就覺得自己非常想念C#中的Lambda表達(dá)式——雖然有些人、有些JS框架會把匿名函數(shù)稱作“Lambda表達(dá)式”,但其實那只相當(dāng)于C#中的“匿名委托/函數(shù)”,而Lambda的(表面)特征是使用簡短的語法模式來反映一個(回調(diào))函數(shù)/過程(或者說動作)的邏輯,而不被“delegate”或者別的什么關(guān)鍵字分散精力。

        出于這樣的原因,我編寫了這個可以轉(zhuǎn)譯JS代碼、把一種特定的模式(pattern)翻譯成函數(shù)定義的模塊。
        在使用這個模塊以后,前面的那個調(diào)用可以變成這個樣子:
        代碼如下:
        eval(function () {
        var ww = (s, document.write(s));
        var ws = (n, ww(' (' + n + ') '));
        pnView(14, (n, ww(' [' + n + '] ')),
        1, 27,
        (n, ww('|< ' + n + ' ')), (n, ww(' ' + n + ' >|')),
        2, ws,
        1, (0, ww(' ... ')),
        2, 2,
        ws, ws
        );
        }.lamda())();

        模塊的完整代碼如下:
        代碼如下:
        /*!
        L-amda "a-Lambda", a module provides Alternate "Lambda" style programming ability for JavaScript.
        Created By NanaLich. 2010-09-08
        This module is published under WTFPL v2, so you just DO WHAT THE Fxxx YOU WANT TO with it.
        */
        !function () {
        function attachEntry(o, a, m) {
        var i, j, n;
        o = [].concat(o);
        //if (!(o instanceof Array)) o = [o];
        while (i = o.shift()) {
        for (j in a) {
        if (!i[n = a[j]]) i[n] = m;
        }
        }
        }
        var rx0 = /^\s*(0|NaN|null)\s*,$/;
        var rx1 = /([\W]\s*)\((\s*0\s*,|(?:\s*[a-z_$][\w$]*\s*,)+)|"(\\[\s\S]|[^\x22])*"|'(\\[\s\S]|[^\x27])*'/gi;
        var rx2 = /\)/g;
        function rxGetFlags(rx) { // 取出正則表達(dá)式的創(chuàng)建選項
        return (rx.global ? 'g' : '') + (rx.ignoreCase ? 'i' : '') + (rx.multiline ? 'm' : '');
        //return /\/([gim]*)$/.exec('' + rx)[1];
        }
        attachEntry(RegExp, ['getFlags'], rxGetFlags);
        attachEntry(RegExp.prototype, ['getFlags'], function () {
        return rxGetFlags(this);
        });

        function translateLambda(s) {
        if (typeof (s) != 'string') s = '' + s;
        var x = new RegExp(rx1.source, rx1.getFlags());
        var y = new RegExp(rx2.source, rx2.getFlags()); // 由于firefox、safari等瀏覽器對全局匹配正則表達(dá)式有過度的優(yōu)化,所以這里采用一種迂回的辦法創(chuàng)建不重復(fù)的正則表達(dá)式實例
        var m, l = 0, r = '';
        while (m = x.exec(s)) {
        var c = m[0], h, p, q, t;
        switch (c.charAt(0)) { // 判斷期待的語法成分
        case '$':
        case ')':
        case ']':
        case '"':
        case "'":
        continue; // 函數(shù)傳參,跳過
        }

        h = m[2];
        if (rx0.test(h))
        h = '';
        else
        h = h.substr(0, h.length - 1); // 去掉末尾的逗號
        r += s.substring(l, p = m.index); // 在結(jié)果字符串上附加之前余留的內(nèi)容
        y.lastIndex = l = p + c.length; // 從逗號之后開始尋找右括號
        while (q = y.exec(s)) {
        q = q.index;
        try {
        t = 'return ' + s.substring(l, q) + ';';
        new Function(t); // 語法測試
        //r += c + 'function(' + h + '){ ' + translateLambda(t) + ' }'; // 翻譯里面的內(nèi)容
        r += m[1] + 'function(' + h + '){ ' + translateLambda(t) + ' }'; // 翻譯里面的內(nèi)容
        x.lastIndex = l = q + 1; // 下一次查找從括號之后開始
        break;
        } catch (ex) { }
        }
        if (!q) l = p; // 說明找不到右括號或者有效的代碼,直接附加所有匹配的內(nèi)容
        }
        try {
        r += s.substr(l);
        if (/[\w$]*|"(\\[\s\S]|[^\x22])*"|'(\\[\s\S]|[^\x27])*'/.exec(r)[0] == 'function') // 粗略判斷產(chǎn)生的是不是函數(shù)(可以應(yīng)付絕大部分情況)
        r = '0,' + r; // 使用這種“怪”形式可以在所有瀏覽器(包括IE)中得到預(yù)期的效果
        new Function(r); // 語法測試
        return r;
        } catch (ex) { // 失敗,返回原文
        return s;
        }
        };

        var lamdaAliases = ["translateLambda", "lambda", "lamda"];
        attachEntry([Function, String], lamdaAliases, translateLambda);
        attachEntry([Function.prototype, String.prototype], lamdaAliases, function () {
        return translateLambda(this);
        });
        } ();

        如果和C#中的Lambda表達(dá)式相比的話,我的這個模塊還是有很多不足的,不過現(xiàn)在這個樣子已經(jīng)讓我很滿意了,至少我不用再寫太多的“function”了。
        簡單來說,這個模塊的規(guī)格特性是這樣的——
        優(yōu)點(diǎn):
        減少編寫代碼時“function”的出現(xiàn)次數(shù);
        使用可以在一般的JavaScript編輯器中正常編輯的語法模式(pattern),直接寫在函數(shù)體中不會導(dǎo)致語法錯誤。
        局限性:
        在任何時候使用這個模塊都必須調(diào)用轉(zhuǎn)譯方法(“translateLambda”、“l(fā)ambda”或者“l(fā)amda”)和eval函數(shù),無法省略;
        如果存在一個函數(shù)A,不可能通過對A進(jìn)行處理來達(dá)到轉(zhuǎn)譯傳遞至A的參數(shù)的目的(也就是說a.lambda()或者類似的操作并不會讓a((x, x * 2))等同于a(function(x){ return x * 2; }));
        不能包含表達(dá)式之外的任何語句、不能包含使用“;”來分隔的多條語句。
        缺點(diǎn):
        連續(xù)出現(xiàn)的括號可能會讓代碼變得難以理解;
        任何編輯器都無法為Lambda表達(dá)式提供語法高亮;
        存在錯誤地轉(zhuǎn)譯現(xiàn)有代碼的可能性——這個模塊選擇進(jìn)行匹配的模式是在正常的代碼中沒有實用價值、也通常不會出現(xiàn)的模式,如:(x, x * 2)等價于單純的x * 2、(0, a.method())等價于單純的a.method(),所以這個缺點(diǎn)影響到實際代碼的可能性無限趨近于0。
        以下是幾種不當(dāng)?shù)挠梅ǎ?
        1、使用這個模塊并不會節(jié)省很多代碼量的時候:本末倒置。
        代碼如下:
        eval(function(){ // 不僅沒減少代碼量,反而還增加了
        window.onload = (0, alert('載入完成!'));
        }.lambda());

        2、對接受參數(shù)的函數(shù)進(jìn)行轉(zhuǎn)譯處理:之前已經(jīng)提到過這種情況。
        代碼如下:
        eval(somefunction.lambda())((x, x.toString(16))); // somefunction可能會產(chǎn)生預(yù)料外的結(jié)果,而且收到的參數(shù)會是x.toString(16)的結(jié)果(如果x在此處并沒有被定義過,還會產(chǎn)生一個“變量不存在”的異常),而非一個回調(diào)函數(shù)。

        3、為了使用此模塊而規(guī)避語法檢查:
        因為使用的是在JavaScript中有效但無實用價值的語法,所以規(guī)避語法檢查是完全沒有必要的。
        代碼如下:
        eval("somefunction((x, x.toString(16)))".lamda()); // 失去了語法檢查,可能在運(yùn)行的時候產(chǎn)生意外

        4、在(偽)Lambda中使用過多的操作,甚至多條語句:
        在設(shè)計這個模塊的時候我并沒有找出可以使用多條語句且可以通過語法檢查的模式(pattern),原因是在Lambda表達(dá)式中使用多條語句時,“function”、“return”等幾個字符所增加的代碼量通常是可以忽略的,這樣去使用Lambda表達(dá)式本身就屬于一種偏離了初衷的做法。
        代碼如下:
        eval(function(){ somefunction((x, y.something(x); return x.toString(16))); }.lamda())(); // 語法錯誤
        eval(function(){ somefunction((x, y.something(x), x.toString(16))); }.lamda())(); // 容易產(chǎn)生理解上的歧義
        eval(function(){ somefunction((x, ++x)); }.lamda())(); // 簡單的表達(dá)式可以被接受

        最佳使用場合:
        現(xiàn)在很多人寫JavaScript的時候喜歡把自己的代碼都寫在一個閉包里面,這樣可以避免全局作用域污染問題,就像這樣:
        代碼如下:
        (function(){
        // 所有的代碼都放在這里
        })();

        ——而這種“大”閉包正好是使用本模塊的最佳場合:
        代碼如下:
        eval(function(){ // 括號前增加eval
        // 所有的代碼都放在這里
        }.lamda())(); // 括號里增加.lamda()

        昨天codeplex抽瘋,代碼和release上傳總出錯。再考慮到這個模塊的使用場合比較有限,不適合缺乏JavaScript經(jīng)驗的人使用,所以不另外提供源代碼打包下載——有需要的話請直接從文中復(fù)制。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法_javascript技巧

        讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法_javascript技巧:但是我后來也跟人說,因為接受的參數(shù)太多,所以如果不把智能提示寫得很清楚的話,連我自己都常常搞不清楚該怎么用。 不過,接受參數(shù)多,除了容易弄錯用法以外,還會產(chǎn)生另一個問題,這也是我編寫出今天發(fā)布的這個東西的原因。 來看一下JS版的頁碼呈現(xiàn)組件的完
        推薦度:
        標(biāo)簽: js 類似 javascript
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 成人爱做日本视频免费| 日韩电影免费在线| 亚洲精品无码永久中文字幕| 青青久久精品国产免费看| selaoban在线视频免费精品| 四虎影视免费永久在线观看 | 亚洲AV无码专区国产乱码电影 | 国产精品自在自线免费观看| 亚洲人成色77777在线观看| 免费激情视频网站| 亚洲精品自产拍在线观看动漫| 可以免费观看的毛片| 91亚洲精品第一综合不卡播放| 182tv免费观看在线视频| 亚洲国产综合精品| 午夜毛片不卡高清免费| 亚洲精品卡2卡3卡4卡5卡区| 中文成人久久久久影院免费观看| 免费无码不卡视频在线观看| 亚洲精品无码久久久久秋霞| 免费真实播放国产乱子伦| 久久嫩草影院免费看夜色| 免费看大美女大黄大色| 精品无码专区亚洲| 亚洲乱码国产乱码精品精| 120秒男女动态视频免费| 亚洲熟女综合色一区二区三区| 免费播放特黄特色毛片| 亚洲色大成网站www永久男同 | 亚洲国产精品无码第一区二区三区 | 国产免费人人看大香伊| 一区二区三区免费视频播放器| 亚洲第一福利视频| 国产麻豆一精品一AV一免费| 亚洲国产成+人+综合| 亚洲国产成人a精品不卡在线| 亚洲欧美日韩中文字幕一区二区三区| 免费人成在线观看网站视频| 日韩精品免费视频| 亚洲黄色网址大全| 日韩亚洲精品福利|