久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Javascript – Arraylike的7種實(shí)現(xiàn)

 haosunzhe 2015-03-27
(點(diǎn)擊上方藍(lán)字,,可快速關(guān)注我們)

jQuery的崛起讓ArrayLike(類數(shù)組)在javascript中大放異彩,,它的出現(xiàn)為一組數(shù)據(jù)的行為(函數(shù))擴(kuò)展提供了基礎(chǔ),。


類數(shù)組和數(shù)組相似,,具有數(shù)組的某些行為,,但是它相比數(shù)組可以更加自由的擴(kuò)展,,它的存在讓一組數(shù)據(jù)的表現(xiàn)不再受限于數(shù)組,,也無(wú)需去污染數(shù)組本身的原型——它來(lái)自javascript對(duì)象的挖掘和擴(kuò)展,,而并非javascript本身就存在的,。簡(jiǎn)單的說(shuō),它來(lái)自數(shù)組,,比數(shù)組更加適合擴(kuò)展,。


這篇文章主要分為以下知識(shí)


  • 鋒芒畢露的ArrayLike

  • ArrayLike的實(shí)現(xiàn)

  • 其他


鋒芒畢露的ArrayLike


如果你已經(jīng)了解了ArrayLike,,這一節(jié)可以略過(guò)。


ArrayLike(類數(shù)組/偽數(shù)組)即擁有數(shù)組的一部分行為,,在DOM中早已表現(xiàn)出來(lái),,而jQuery的崛起讓ArrayLike在javascript中大放異彩。正如它的翻譯一樣:它類似于數(shù)組,。


ArrayLike對(duì)象的精妙在于它和javascript原生的Array類似,,但是它是自由構(gòu)建的,它來(lái)自開發(fā)者對(duì)javascript對(duì)象的擴(kuò)展,,也就是說(shuō):對(duì)于它的原型(prototype)我們可以自由定義,,而不會(huì)污染到j(luò)avascript原生的Array。


過(guò)去針對(duì)一組數(shù)據(jù)的擴(kuò)展是下面這個(gè)樣子的:


//污染Array實(shí)現(xiàn)擴(kuò)展

Array.prototype.demo = function () {

//check

};

var test = [];

test.demo();


上面代碼你們懂的,,污染了Array,,在協(xié)同式開發(fā)中這簡(jiǎn)直就是作孽啊——ArrayLike應(yīng)此誕生。


ArrayLike讓你對(duì)一組數(shù)據(jù)的擴(kuò)展不再受限于Array本身,,同時(shí)也不會(huì)影響到Array,,說(shuō)白了就是:一組數(shù)據(jù),肯定是有數(shù)組來(lái)存,,但是如果要對(duì)這組數(shù)據(jù)進(jìn)行擴(kuò)展,,會(huì)影響到數(shù)組原型,ArrayLike的出現(xiàn)則提供了一個(gè)中間數(shù)據(jù)橋梁,,ArrayLike有數(shù)組的特性,, 但是對(duì)ArrayLike的擴(kuò)展并不會(huì)影響到原生的數(shù)組。舉個(gè)栗子:


爸爸媽媽對(duì)你期望很高,,你要好好學(xué)習(xí),,但是舍友基佬教會(huì)了你打dota,整天拉你打dota讓你沒(méi)時(shí)間看書學(xué)習(xí),,結(jié)果呢,,就是打得一手好dota學(xué)習(xí)掉下去了——但是如果,你開了分身斧,,讓你的分身去打dota,,你自己仍然好好學(xué)習(xí),dota學(xué)習(xí)兩不誤,,而且你的分身不僅僅可以打dota,,也可以去打wow,把妹,,做你做不到的事情,,是不是覺(jué)得這樣不就碉堡了么!??!


沒(méi)錯(cuò),,ArrayLike就是要干這么碉堡的事情。


常見(jiàn)的ArrayLike有下面這幾個(gè),,詳見(jiàn):其他,。


  • Arguments

  • NodeList

  • StyleSheetList

  • HTMLCollection

  • HTMLFormControlsCollection (繼承HTMLCollection)

  • HTMLOptionsCollection(繼承HTMLCollection)

  • HTMLAllCollection

  • DOMTokenList


ArrayLike的實(shí)現(xiàn)


第一種 – 通過(guò)閉包實(shí)現(xiàn):


通過(guò)閉包實(shí)現(xiàn),內(nèi)部采用一個(gè)Array作為基礎(chǔ),,API是針對(duì)數(shù)組進(jìn)行操作,,在API的實(shí)現(xiàn)上較差。并且不支持直接通過(guò)索引(array[0])來(lái)訪問(wèn)元素,,通過(guò)閉包實(shí)現(xiàn)上會(huì)丟失instanceof的判定,,優(yōu)點(diǎn)是夠輕。


!function () {

//通過(guò)閉包實(shí)現(xiàn)

var List = function () {

var list = [],

self = {

constructor: List,

//如果希望更像原生一點(diǎn),,將length定義為屬性,,那么length則需要自己維護(hù)

length: function () { return list.length; },

add: function (item) {

list.push(item);

},

eq: function (index) {

return list[index];

}

};

return self;

};

//測(cè)試

console.group('第一種 - 通過(guò)閉包實(shí)現(xiàn)');

var demo = new List();

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:red;');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

//無(wú)法通過(guò)索引demo[0]這種方式訪問(wèn)

console.log('成員:[ ' + demo.eq(0) + ' , ' + demo.eq(1) + ' ]');

console.log('length:' + demo.length());

//注意看demo對(duì)象

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第二種 – 通過(guò)繼承實(shí)現(xiàn):


主要亮點(diǎn)(應(yīng)用)在保留Array的API,在Array上二次封裝,,可以通過(guò)索引來(lái)訪問(wèn),。


!function () {

//通過(guò)繼承數(shù)組實(shí)現(xiàn),數(shù)組原生方法會(huì)被繼承過(guò)來(lái)

var List = function () { };

List.prototype = [];

List.prototype.constructor = List;

List.prototype.add = function (item) {

this.push(item);

};

//測(cè)試

console.group('第二種 - 通過(guò)繼承實(shí)現(xiàn)');

var demo = new List();

//源于繼承

demo.push('Array - push()');

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:blue;');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

//注意看demo對(duì)象

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第三種 – 通過(guò)自我維護(hù)實(shí)現(xiàn):


在增刪改上需要自我維護(hù)length,,相比下來(lái)很是折騰和繁瑣,,只是提供一種代碼思路,并不提倡,,可以通過(guò)索引訪問(wèn),,


!function () {

//通過(guò)自動(dòng)維護(hù)length實(shí)現(xiàn)

var List = function () {

this.length = 0;

};

List.prototype.add = function (item) {

//讓對(duì)象模擬Array的行為

this[this.length++] = item;

};

console.group('第三種 - 通過(guò)自我維護(hù)實(shí)現(xiàn)');

var demo = new List();

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:blue');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

//注意看demo對(duì)象

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第四種 – 針對(duì)第一種優(yōu)化:


在add中通過(guò)Array原生的APIArray.prototype.push來(lái)實(shí)現(xiàn),原理是只要調(diào)用過(guò)Array原生的增刪改API操作函數(shù)(僅第一次即可),,則可以通過(guò)索引來(lái)訪問(wèn)元素,,但是instanceof的判定仍未修復(fù)。


!function () {

//第四種Array-Like

var List = function () {

var self = {

constructor: List,

length: 0,

add: function (item) {

//本質(zhì)在這里,,交給Array的自動(dòng)維護(hù)

[].push.call(this, item);

}

};

return self;

};

console.group('第四種 - 針對(duì)第一種優(yōu)化');

var demo = new List();

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:red;');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第五種 – 修復(fù)instenceof判定:


這種修復(fù)有點(diǎn)勉強(qiáng),,因?yàn)樵趇e下并沒(méi)有__proto__,所以這里所謂的修復(fù)只不過(guò)是針對(duì)現(xiàn)代瀏覽器而已,,只是提供一種思路,,關(guān)于instenceof請(qǐng)參考請(qǐng)參考:其他。


!function () {

//第五種,,我們看見(jiàn)上面那種instanceOf并不能返回正確的結(jié)果,于是我們修正它

var List = function () {

/*

instanceof 檢測(cè)一個(gè)對(duì)象A是不是另一個(gè)對(duì)象B的實(shí)例的原理是:

查看對(duì)象B的prototype指向的對(duì)象是否在對(duì)象A的[[prototype]]鏈上,。

如果在,,則返回true,如果不在則返回false。

不過(guò)有一個(gè)特殊的情況,,當(dāng)對(duì)象B的prototype為null將會(huì)報(bào)錯(cuò)(類似于空指針異常),。

reference:http://kb.cnblogs.com/page/77478/

*/

self = {

constructor: List,

length: 0,

//強(qiáng)制引用__proto__,IE并不支持

__proto__: List.prototype,

add: function (item) {

push.call(this, item);

}

},

//cache

push = Array.prototype.push;

return self;

};

console.group('第五種 - 修復(fù)instenceOf判定');

var demo = new List();

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:blue;');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第六種 – jQuery的實(shí)現(xiàn):


jQuery構(gòu)造函數(shù)繁瑣的實(shí)現(xiàn)不僅僅只是為了去new化,,同時(shí)也修復(fù)了針對(duì)jQuery對(duì)象的判定,巧妙的將原型重新指向,,讓instenceof可以在原型鏈中查找到j(luò)Query構(gòu)造函數(shù),,使得instenceOf判定有效,讓jQuery直逼真正的javascript對(duì)象,。


!function () {

//jQuery Array-Like實(shí)現(xiàn)

var jQuery = function () {

return new jQuery.fn.init();

}, push = Array.prototype.push;

jQuery.fn = jQuery.prototype = {

constructor: jQuery,

length: 0,

add: function (item) {

//使用Array.prototype.push添加元素,,會(huì)自動(dòng)維護(hù)length

push.call(this, item);

}

};

jQuery.fn.init = function () {

return this;

};

//漂亮的重置prototype

jQuery.fn.init.prototype = jQuery.fn;

console.group('第六種 - jQuery的實(shí)現(xiàn)');

var demo = new jQuery();

demo.add('List - add()');

console.log('demo instanceof jQuery : %c' + (demo instanceof jQuery), 'color:blue');

console.log('demo.constructor === jQuery : %c' + (demo.constructor === jQuery), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第七種 – 最簡(jiǎn)單的實(shí)現(xiàn):


并沒(méi)有采用閉包,而是通過(guò)定義原型實(shí)現(xiàn),,實(shí)現(xiàn)方法類似第四種,,但是原型指向正確,instenceof判定有效,。


//最簡(jiǎn)單的類數(shù)組實(shí)現(xiàn)

!function () {

var List = function () { }, push = Array.prototype.push;

List.prototype = {

constructor: List,

length: 0,

add: function (item) {

push.call(this, item);

}

};

console.group('第七種 - 最簡(jiǎn)單的實(shí)現(xiàn)');

var demo = new List();//只是需要new

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:blue;');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

console.log(demo);

console.groupEnd();

}();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



第八種 – jQuery拆解版:


為了更好的理解jQuery的構(gòu)造函數(shù)實(shí)現(xiàn),,所以給出了這種,jQuery.fn.init就是本例中的ArrayLike對(duì)象,,jQuery只是把init掛載到j(luò)Query.prototype上了而已,。


(function () {

var List = function () {

return new ArrayLike();

}, ArrayLike = function () {//這個(gè)array-like就是jQuery拆解版的實(shí)現(xiàn)

};

List.prototype = {

constructor: List,

length: 0,

add: function (item) {

Array.prototype.push.call(this, item);

}

};

//就是jQuery的jQuery.fn.init.prototype = jQuery.fn;

ArrayLike.prototype = List.prototype;

//測(cè)試

console.group('第八種 - jQuery拆解版');

var demo = List(); //這樣就不用new了

demo.add('List - add()');

console.log('demo instanceof List : %c' + (demo instanceof List), 'color:blue;');

console.log('demo.constructor === List :%c' + (demo.constructor === List), 'color:blue');

console.log('[ ' + demo[0] + ' , ' + demo[1] + ' ]');

console.log('length:' + demo.length);

console.log(demo);

console.groupEnd();

})();


運(yùn)行結(jié)果和demo對(duì)象結(jié)構(gòu):



其實(shí)應(yīng)該叫做類數(shù)組對(duì)象的7次實(shí)現(xiàn)…有點(diǎn)標(biāo)題黨的意思…..不要打臉…


其他


  • 完整源碼:https://github.com/linkFly6/linkfly.so/blob/master/LinkFLy/LinkFly/ArrayLike.js

  • 參考文章:JavaScript類數(shù)組對(duì)象參考

  • 參考文章:理解instanceof實(shí)現(xiàn)原理



來(lái)自:linkFly

鏈接:http://www.cnblogs.com/silin6/p/4309925.html



    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多