The rise of jquery makes the arraylike (class array) shine in JavaScript, which provides the basis for the behavior (function) expansion of a set of data.
A class array and arrays are similar, have some behavior of the array, but it can be more freely extended than the array, its existence so that the performance of a set of data is no longer limited to the array, and does not need to pollute the array itself prototype-it comes from the JavaScript object Mining and extension, It's not the JavaScript itself that exists. Simply put, it comes from an array, which is more suitable for expansion than arrays.
This article is original in Linkfly, the original address.
This article is mainly divided into the following knowledge
- Edged's Arraylike
- The realization of Arraylike
- Other
Edged's Arraylike
If you already know Arraylike, this section can be skipped.
Arraylike (class array/pseudo-array) , which has part of the behavior of the array, has long been shown in the DOM, and the rise of jquery has made Arraylike shine in JavaScript. As it is translated: it resembles an array.
The subtlety of the Arraylike object is that it is similar to JavaScript's native array, but it is free to build, it comes from the developer's extension of the JavaScript object, that is to say: for its prototype (prototype) we can freely define, Without contaminating the original JavaScript array.
The previous extensions for a set of data are as follows:
The pollution Array implements the extended Array.prototype.demo = function () { //check }; var test = []; Test.demo ();
The above code you know, contaminated the array, in the collaborative development of this is a sin ah--arraylike should be born.
Arraylike lets you extend a set of data is no longer limited by the array itself, but also does not affect the array, it is said: a set of data, there must be an array to save, but if you want to extend this set of data, will affect the array prototype, The advent of Arraylike provides an intermediate data bridge, Arraylike has the properties of the array, but the extension to Arraylike does not affect the native array. Give me a chestnut:
Mom and Dad have high expectations for you, you have to study hard, but the house friends of the Yankees taught you to play DotA, all day pull you play DotA so you do not have time to read the study, the result, is to play a good DotA learning fell down-but if you open a fen axe, let your avatar to play DotA, you still study hard, DotA learning two not wrong, and your avatar can not only play DotA, can also go to play Wow, the sister, do you do not do things, do not think this is not the bunker it!!!
Yes, Arraylike is going to do such a bunker thing.
Common Arraylike have the following several, see: Other.
- Arguments
- NodeList
- Stylesheetlist
- Htmlcollection
- Htmlformcontrolscollection (inheriting htmlcollection)
- Htmloptionscollection (inheriting htmlcollection)
- Htmlallcollection
- Domtokenlist
The first implementation of Arraylike is implemented by closures:
The implementation of the closure, the internal use of an array as the basis for the API is to operate on the array, the implementation of the API is poor. And does not support directly through the index (array[0]) to access elements, through the closure implementation will be lost instanceof judgment, the advantage is light enough.
!function () {//implemented by a closure var list = function () {var list = [], self = { Constructor:list,//If you want to be more like a native, define length as a property, then length needs to be maintained by itself Length:f Unction () {return list.length;}, Add:function (item) {List.push (item); }, Eq:function (index) {return list[index]; } }; return self; }; Test Console.group (' first-implemented by closures '); 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 '); Cannot access Console.log (' Member: [' + demo.eq (0) + ', ' + demo.eq (1) + ') in this way via index demo[0]; Console.log (' Length: ' + demo.length ()); Watch the de.Mo Object Console.log (demo); Console.groupend (); }();
Run the results and the Demo object structure:
The second type-implemented by inheritance:
The main highlight (APP) is the API that retains the array, which is encapsulated two times on an array and can be accessed through an index.
!function () { //by inheriting an array implementation, the array native method is inherited by the var List = function () {}; List.prototype = []; List.prototype.constructor = List; List.prototype.add = function (item) { This.push (item); }; Test Console.group (' second type-through inheritance '); var demo = new List (); Originating from the inheritance of 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); Watch the Demo object console.log (demo); Console.groupend (); } ();
Run the results and the Demo object structure:
The third kind-through self-maintenance to achieve:
In the additions and deletions need self-maintenance length, compared to down is very frustrating and cumbersome, just provide a code idea, do not advocate, can be accessed through the index,
!function () { //by Automatic maintenance length implementation var List = function () { this.length = 0; }; List.prototype.add = function (item) { //Let the object simulate the behavior of array this[this.length++] = Item; }; Console.group (' The third-realization through self-maintenance '); 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); Watch the Demo object console.log (demo); Console.groupend (); } ();
Run the results and the Demo object structure:
Fourth type-for the first optimization:
array.prototype.push . The principle is that the element can be accessed through an index as long as the array native additions and deletions are changed to the API action function (only the first time), but the decision of instanceof is still not fixed.
!function () { ///Fourth array-like var List = function () { var self = { constructor:list, length:0,
add:function (item) { //essence here, to the automatic maintenance of the array [].push.call (this, item); } }; return self; }; Console.group (' fourth type-for the first optimization '); 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 (); } ();
Run the results and the Demo object structure:
Fifth-fix instenceof judgment:
This kind of repair is a bit reluctant, because in IE there is no __proto__ , so the so-called fix is only for the modern browser only, Just provide a way of thinking about instenceof please refer to: other.
!function () {///fifth, we see that the above instanceof does not return the correct result, so we fix it var List = function () {/* Instanceof detects if an object A is an instance of another object B by looking at whether the object pointed to by prototype of Object B is on the [[prototype]] chain of object A. Returns true if it is, or false if it is not. There is a special case, however, when the prototype of object B is null, it will be an error (similar to a null pointer exception). reference:http://kb.cnblogs.com/page/77478/*/self = {constructor:list, length:0,//force reference __proto__,ie does not support __proto__: List.prototype, Add:functi On (item) {Push.call (this, item); }},//cache push = Array.prototype.push; return self; }; Console.group (' Fifth kind-fix instenceof judgment '); 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 (); }();
Run the results and the Demo object structure:
The sixth type-jquery implementation:
The tedious implementation of the jquery constructor is not just for the sake of new, but also fixes the decision for jquery objects, subtly re-pointing the prototype, allowing instenceof to find the jquery constructor in the prototype chain, making Instenceof is effective, so jquery is pushing the real JavaScript object.
!function () {//jquery Array-like implements var jQuery = function () {return new jQuery.fn.init (); }, push = Array.prototype.push; Jquery.fn = Jquery.prototype = {constructor:jquery, length:0, Add:function (item) { Using Array.prototype.push to add elements, the length Push.call (this, item) is automatically maintained; } }; JQuery.fn.init = function () {return this; }; Nice reset prototype jQuery.fn.init.prototype = Jquery.fn; Console.group (' The sixth kind-implementation of jquery '); 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 (); }();
Run the results and the Demo object structure:
Seventh-The simplest implementation:
Not using closures, but by defining the implementation of the prototype, the implementation method is similar to the fourth, but the prototype point is correct,instenceof decision valid.
The simplest class array implementation !function () { var List = function () {}, push = Array.prototype.push; List.prototype = { constructor:list, length:0, add:function (item) { Push.call (this, item); } }; Console.group (' seventh type-simplest implementation '); var demo = new List ();//Just need 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 (); } ();
Run the results and the Demo object structure:
Eighth Type-jquery disassembly version:
in order to better understand the implementation of JQuery's constructor, so given this, jquery.fn.init is in this case arraylike object, jquery simply mounts init to jquery.prototype .
(function () {var List = function () {RE Turn new Arraylike (); }, Arraylike = function () {//This array-like is the implementation of the jquery disassembly version}; List.prototype = {constructor:list, length:0, Add:function (item) {Ar Ray.prototype.push.call (this, item); } }; Is the jQuery.fn.init.prototype of jQuery = Jquery.fn; Arraylike.prototype = List.prototype; Test Console.group (' eighth type-jquery disassembly version '); var demo = List (); This will not be 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 (); })();
Run the results and the Demo object structure:
In fact, it should be called 7 implementations of class array objects ... A bit of a title party means ..... Don't hit the face ...
Other
- Full Source: Https://github.com/linkFly6/linkfly.so/blob/master/LinkFLy/LinkFly/ArrayLike.js
- Reference article: JavaScript class Array Object reference
- Reference article: Understanding Instanceof Implementation Principles
Linkfly Original: http://www.cnblogs.com/silin6/p/ArrayLike.html Source: www.cnblogs.com/silin6/statement: Hey! You cuff the above a big paragraph, I think you should not mind by the way, I hope you can in every reference to retain this paragraph of the statement, respect for the author's hard work, this article and blog Park to share.
7 Implementations of Javascript-arraylike