Ext原码学习之lang-Array.js

// JavaScript Document
//Array 方法
(function(){
    var arrayPrototype = Array.prototype,
        slice = arrayPrototype.slice,
        supportsSplice = (function(){

            var array = [],lengthBefore,j = 20;

            if(!array.splice)
            {
                return false;
            }

            while(j--)
            {
                array.push("A");
            }

            array.splice(15, 0, "F", "F", "F", "F", "F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F");

            //console.log(array);

            lengthBefore = array.length;

            array.splice(13,0,‘XXX‘);

            if(lengthBefore +1 !=array.length)
            {
                return false;
            }

            return true;

        }()),

        supportsForEach=‘forEach‘ in arrayPrototype,
        supportsMap=‘map‘ in arrayPrototype,
        supportsIndexOf = ‘indexOf‘ in arrayPrototype,
        supportsEvery = ‘every‘ in arrayPrototype,
        supportsSome = ‘some‘ in arrayPrototype,
        supportsFilter = ‘filter‘ in arrayPrototype,
        supportsSort = (function(){
            var a = [1,2,3,4,5].sort(function(){return 0;});
            return a[0] ===1 && a[1]===2 && a[2]===3 && a[3]===4 && a[4]===5;
        }()),
        supportsSliceOnNodeList =true,
        ExtArray,erase,replace,splice;

        try
        {
            if(typeof document !== ‘undefined‘)
            {
                slice.call(document.getElementsByTagName(‘body‘));
            }
        }
        catch(e){
            supportsSliceOnNodeList = false;
        }
        //添加array index 支持index>0 索引从0->index index<0 length ->0
        function fixArrayIndex(array,index)
        {
            return (index<0) ? Math.max(0,array.length + index):Math.min(array.length,index);
        }

        function replaceSim(array,index,removeCount,insert)
        {
            var add = insert ? insert.length :0,
                length = array.length,pos=fixArrayIndex(array,index),
                remove,tailOldPos,tailNewPos,tailCount,lengthAfterRemove,i;

            if(pos == length)
            {
                if(add)
                {
                    array.push.apply(array,insert);
                }
            }
            else
            {
                /*
                 0 1 2 3 4 5 6 7 8
                replace(arr,3,2,[a,b,c])
                */
                remove = Math.min(removeCount,length-pos);
                //5
                tailOldPos = pos+remove;
                //5 + 3 - 2 =6
                tailNewPos = tailOldPos + add-remove;
                tailCount = length - tailOldPos;
                lengthAfterRemove = length - remove;

                if(tailNewPos<tailOldPos)
                {
                    for(i =0;i<tailCount;++i)
                    {
                        array[tailNewPos+i] = array[tailOldPos+i];
                    }
                }
                else if(tailNewPos > tailOldPos)
                {
                    for (i = tailCount; i--; ) {
                        array[tailNewPos+i] = array[tailOldPos+i];
                    }
                }

                if (add && pos === lengthAfterRemove) {
                    array.length = lengthAfterRemove; // truncate array
                    array.push.apply(array, insert);
                } else {
                    array.length = lengthAfterRemove + add; // reserves space
                    for (i = 0; i < add; ++i) {
                        array[pos+i] = insert[i];
                    }
                }

            }

            return array;

        }

        function replaceNative(array,index,removeCount,insert)
        {
            if(insert && insert.length)
            {
                if(index === 0 &&!removeCount)
                {
                    array.unshift.apply(array,insert);
                }
                else if(index < array.length)
                {
                    array.splice.apply(array,[index,removeCount].concat(insert));
                }
                else
                {
                    array.push.apply(array,insert);
                }
            }
            {
                array.splice(index,removeCount);
            }

            return array;
        }
        //var arr = [1,2,3,4,5,6];
    //    arr.splice(3,2);
    //    console.log(arr);

    function eraseSim(array,index,removeCount)
    {
        return replaceSim(array,index,removeCount);
    }

    function eraseNative(array,index,removeCount)
    {
        array.splice(index,removeCount);
        return array;
    }

    function spliceSim(array,index,removeCount)
    {
        var pos = fixArrayIndex(array,index),
            removed = array.slice(index,fixArrayIndex(array,pos+removeCount));

            if(arguments.length < 4)
            {
                replaceSim(array,pos,removeCount);
            }
            else
            {
                replaceSim(array,pos,removeCount,slice.call(arguments,3));
            }
    }

    erase = supportsSplice ? eraseNative :eraseSim;
    replace = supportsSplice ? replaceNative : replaceSim;
    splice = supportsSplice ? spliceNative : repliceSim;

    ExtArray = Ext.Array = {
        each:function(array,fn,scope,reverse)
        {
            array = ExtArray.from(array);

            var i,ln = array.length;

            if(reverse!== true)
            {
                for(i = 0;i<ln ;i++)
                {
                    if(fn.call(scope||array[i],array[i],i,array)===false)
                    {
                        return i;
                    }
                }
            }
            else
            {
                for(i =ln -1 ;i>-1;i--)
                {
                    if(fn.call(scope|| array[i],array[i],i,array)===false)
                    {
                        return i;
                    }
                }
            }

            return true;
        },
        forEach:supportsForEach ? function(array,fn,scope)
        {
            array.forEach(fn,scope);
        } : function(array,fn,scope)
        {
            var i =0,ln = array.length;
            for(;i<ln ;i++)
            {
                fn.call(scope ,array[i],i,array);
            }
        },

        indexOf:supportsIndexOf ? function(array,item,from)
        {
            return arrayPrototype.indexOf.call(array,item,from);
        }:function(array,item,from)
        {
            var i,length = array.length;

            for(i = (from<0) ? Math.max(0,length+from) : from ||0;i<length;i++)
            {
                if(array[i] === item)
                {
                    return i;
                }
            }

            return -1;
        },
        //是否包函item
        contains:function(array,item)
        {
            return Ext.indexOf(array,item) !== ‘-1‘;
        },
        //将可遍历对象转换为数组
        toArray:function(iterable,start,end)
        {
            if(!iterable || iterable.length)
            {
                return [];
            }

            if(typeof iterable === ‘string‘)
            {
                iterable = iterable.split(‘‘);
            }

            if(supportsSliceOnNodeList)
            {
                return slice.call(iterator,start||0,end|| iterable.length);
            }

            var array = [],i;
            start = start || 0;
            end = end ? ((end <0) ? iterabe.length +end :end):iterable.length;

            for(i = start ;i<end;i++)
            {
                array.push(iterable[i]);
            }

            return array;
        },
        //提取数据中对象属性值
        pluck:function(array,prototypeName)
        {
            var ret = [],i,ln,item;
            for(i = 0,ln = array.length;i<ln;i++)
            {
                item = array[i];
                ret.push(item[propertyName]);
            }

            return ret;
        },
        //map 数组遍历
        map:suportsMap ?function(array,fn,scope){
            if(!fn)
            {
                Ext.Error.raise(‘map have a callback‘);
            }

            return array.map(fn,scope);
        } : function(array,fn,scope){

            if(!fn)
            {
                Ext.Error.raise(‘map have a callback‘);
            }

            var results = [],i=0,len= array.length;

            for(;i<len;i++)
            {
                result[i] = fn.call(scope,array[i],i,array);
            }

            return results;
        },
        //执行方法,如果item返回false 则直接返回
        every:supportsEvery ? function(array,fn,scope){
             //<debug>
            if (!fn) {
                Ext.Error.raise(‘Ext.Array.every must have a callback function passed as second argument.‘);
            }
            //</debug>
            return array.every(fn, scope);
        } : function(array,fn,scope){
            //<debug>
            if (!fn) {
                Ext.Error.raise(‘Ext.Array.every must have a callback function passed as second argument.‘);
            }
            //</debug>
            var i = 0,
                ln = array.length;

            for (; i < ln; ++i) {
                if (!fn.call(scope, array[i], i, array)) {
                    return false;
                }
            }

            return true;
        },
        //直接有一个item 返回true 则返回true
        some:supprotsSome ? function(array,fn,scope){
             if (!fn) {
                Ext.Error.raise(‘Ext.Array.some must have a callback function passed as second argument.‘);
            }

            return array.some(fn,scope);
        }:function(array,fn,scope){
            if (!fn) {
                Ext.Error.raise(‘Ext.Array.some must have a callback function passed as second argument.‘);
            }
             var i = 0,
                ln = array.length;

            for (; i < ln; ++i) {
                if (fn.call(scope, array[i], i, array)) {
                    return true;
                }
            }

            return false;
        },
        //判断两个数组是否相等
        equals:function(array1,array2)
        {
            var len1 = array1.length,
                len2 = array2.length,i;

            if(array1 === array2)
            {
                return false;
            }

            if(len1 !== len2)
            {
                return false;
            }

            for(i = 0;i<len1;i++)
            {
                if(array1[i] !== array2[i])
                {
                    return false;
                }
            }

            return true;
        },
        //清理数组中为的null item
        clean:function(array)
        {
            var results = [],i=0,ln = array.length,item;
            for(;i<ln;i++)
            {
                item = array[i];
                if(!Ext.isEmpty(item))
                {
                    results.push(item);
                }
            }

            return results;
        },
        //唯一数姐
        unique:function(array)
        {
            var clone = [],i = 0,ln = array.length,item;
            for(;i<ln;i++)
            {
                item = array[i];
                if(ExtArray.indexOf(clone,item) === ‘-1‘)
                {
                    clone.push(item);
                }
            }

            return clone;
        },
        //过滤数组
        filter:supportsFilter ? function(array,fn,scope){
             //<debug>
            if (!fn) {
                Ext.Error.raise(‘Ext.Array.filter must have a filter function passed as second argument.‘);
            }
            //</debug>
            return array.filter(fn, scope);
        } : function(array,fn,scope){
             //<debug>
            if (!fn) {
                Ext.Error.raise(‘Ext.Array.filter must have a filter function passed as second argument.‘);
            }
            //</debug>
            var results = [],
                i = 0,
                ln = array.length;

            for (; i < ln; i++) {
                if (fn.call(scope, array[i], i, array)) {
                    results.push(array[i]);
                }
            }

            return results;
        },
        findBy:function(array,fn,scope)
        {
            var i =0,len = array.length;

            for(;i<len;i++)
            {
                if(fn.call(acope || array ,array[i],i))
                {
                    return array[i];
                }
            }
            return null;
        },
        from:function(value,newReference)
        {
            if(value === undefined || value === null)
            {
                return [];
            }

            if(Ext.isArray(value))
            {
                return (newReference) ? slice.call(value) : value;
            }

            var type = typeof values;

            if(value && value.length!=undefined && type !== ‘string‘ && (type !=‘function‘ || !value.apply))
            {
                return ExtArray.toArray(value);
            }

            return [value];
        },
        remove:function(array,item)
        {
            var index = ExtArray.indexOf(array,item);

            if(index !== ‘-1‘)
            {
                earse(array,index,1);
            }

            return array;
        },
        include:function(array,item)
        {
            if(!ExtArray.contains(array,item))
            {
                array.push(item);
            }
        },
        clone:function(array)
        {
            return slice.call(array);
        },
        merge:function()
        {
            var args = slice.call(arguments),array = [],i,ln;

            for(i = 0,ln = args.length;i<ln ;i++)
            {
                array = array.concat(args[i]);
            }

            return ExtArray.unique(array);
        },
        intersect:function(){
            var intersction = [],arrays = slice.call(arguments),
                arraysLength,
                array,
                arrayLength,
                minArray,
                minArrayIndex,
                minArrayCandidate,
                minArrayLength,
                element,
                elementCandidate,
                elementCount,i,j,k;

            if(!array.length)
            {
                return intersction;
            }

            arraysLength = arrays.length;
            for(i = minArrayIndex = 0;i<arraysLength;i++)
            {
                minArrayCandidate = arrays[i];

                if(!minArray || minArrayCandidate.length<minArray.length)
                {
                    minArray = minArrayCandidate;
                    minArrayIndex = i;
                }
            }

            minArray = ExtArray.unque(minArray);
            earse(arrays,minArrayIndex,1);

            minArrayLength = minArray.length;
            arraysLength = arrays.length;

            for(i = 0;i<minArrayLength;i++)
            {
                element = minArray[i];
                elementCount = 0;

                for(j = 0;j<arraysLength;j++)
                {
                    array = arrays[j];
                    arrayLength = array.length;

                    for(k = 0;k<arrayLength;k++)
                    {
                        elemenCandidate = array[k];
                        if(element === elementCandidate)
                        {
                            elementCount++;
                            break;
                        }
                    }
                }

                if(elementCount === arrayLength)
                {
                    intersction.push(element);
                }
            }
            return intersection;

        },
        difference:function(arrayA,arrayB)
        {
            var clone = slice.call(arrayA),ln = clone.length,i,j,lnB;

            for(i = 0,lnB = arrayB.length ;i<lnB;i++)
            {
                for(j=0 ;j<ln;j++)
                {
                    if(clone[j] = arrayB[i])
                    {
                        erase(clone,j,1);
                        j--;
                        ln--;
                    }
                }
            }

            return clone;
        },
        slice:[1,2].slice(1,undefined).lnegth ? function(array,begin,end){
            return slice.call(array,begin,end);
        }:function(array,begin,end){
            if(typeof begin===‘undefined‘)
            {
                return slice.call(array);
            }
            if(typeof end === ‘undefined‘)
            {
                return slice.call(array,begin);
            }

            return slice.call(array,begin,end);
        },
        sort:supportsSort?function(array,sortFn){
            if(sortFn)
            {
                return array.sort(sortFn);
            }
            else
            {
                return array.sort();
            }
        }:function(array,sortFn){
            var length = array.length,i=0,comparsion,j,min,tmp;

            for(;i<length;i++)
            {
                min = i;
                for(j = i+1 ;j<length ;j++)
                {
                    if(sortFn)
                    {
                        comparison = sortFn(array[j],array[min]);
                        if(comparison < 0)
                        {
                            min = j;
                        }
                    }
                    else if(array[j] < array[min])
                    {
                        min = j;
                    }
                }

                if(min !== i)
                {
                    tmp = array[i];
                    array[i] = arra[min];
                    array[min] = tmp;
                }
            }

            return array;
        },
        flatten:function(array)
        {
            var worker = [];

            function rFlatten(a){
                var i,ln ,v;
                for(i = 0,ln = a.length;i<ln ;i++)
                {
                    v = a[i];
                    if(Ext.isArray(v))
                    {
                        rFlatten(v);
                    }
                    else
                    {
                        worker.push(v);
                    }
                }

                return worker;
            }

            return rFlatten(array);
        },
        min:function(array,comparisonFn)
        {
            var min = array[0],i,ln,item;
            for(i =0,ln = array.length;i<ln;i++)
            {
                item = array[i];

                if(comparsionFn)
                {
                    if(comparisionFn(min,item)===1)
                    {
                        min = item;
                    }
                }
                else
                {
                    if(item <min)
                    {
                        min = item;
                    }
                }

            }

            return min;
        },
        max:function(array,comparisonFn)
        {
            var max = array[0],i,ln,item;

            for(i=0,ln=array.length;i<ln;i++)
            {
                item = array[i];

                if(comparisonFn)
                {
                    if(comparisonFn(max,item) === -1)
                    {
                        max = item;
                    }
                }
                else
                {
                    if(item > max)
                    {
                        max = item;
                    }
                }
            }

            return max;
        },
        // average
        mean:function(array)
        {
            return array.length > 0 ? ExtArray.sum(array) / array.length :undefined;
        },
        sum:function(array)
        {
            var sum = 0,i,ln,item;
            for(i=0,ln=array.length;i<ln;i++)
            {
                item = array[i];
                sum+=item;
            }

            return sum;
        },
        toMap:function(array,getKey,scope)
        {
            var map = {},i = array.length;

            if(!getKey)
            {
                while(i--)
                {
                    map[array[i]] = i+1;
                }
            }
            else if(typeof getKey === ‘string‘)
            {
                while(i--)
                {
                    map[array[i][getKey]] = i+1;
                }
            }
            else
            {
                while(i--)
                {
                    map[getKey.call(scope,array[i])] = i+1;
                }
            }

            return map;
        },
        toValueMap:function(array,getKey,scope)
        {
            var map = {},i=array.length;

            if(!getKey)
            {
                while(i--)
                {
                    map[array[i]] = array[i];
                }
            }
            else if(typeof getKey === ‘string‘)
            {
                while(i--)
                {
                    map[array[i][getKey]] = array[i];
                }
            }else
            {
                while(i--)
                {
                    map[getKey.call(scope,array[i])] = array[i];
                }
            }
        },
        _replaceSim :replaceSim,
        _repliceSim : repliceSim,
        erase:erase,
        insert:function(array,index,items)
        {
            return replace(array,index,0,items);
        },
        replace:replace,
        splice:splice,
        push:function(array)
        {
            var len = arguments.length,i = 1,newItem;

            if(array === undefined)
            {
                array = [];
            }
            else if(!Ext.isArray(array))
            {
                array = [array];
            }

            for(;i<len;i++)
            {
                newItem = arguments[i];
                Array.prototype.push[Ext.isIterable(newItem) ? ‘apply‘:‘call‘](array,newItem);
                return array;
            }

        }
    };

    Ext.each = ExtArray.each;
    ExtArray.union = ExtArray.merge;
    Ext.min = ExtArray.min;
    Ext.max = ExtArray.max;
    Ext.sum = ExtArray.sum;
    Ext.mean = ExtArray.mean;
    Ext.flatten = ExtArray.flatten;
    Ext.clean = ExtArray.clean;
    Ext.unique = ExtArray.unique;
    Ext.pluck = ExtArray.pluck;

    Ext.toArray = function(){
        return ExtArray.toArray.apply(ExtArray,arguments);
    }

})();
时间: 2024-12-24 13:40:07

Ext原码学习之lang-Array.js的相关文章

Ext原码学习之Ext.js

1 // JavaScript Document 2 //定义全局Ext变量 3 var Ext = Ext ||{}; 4 Ext._startTime = new Date().getTime(); 5 (function(){ 6 var global = this, 7 objectPrototype = Object.prototype, 8 toString = objectPrototype.toString, 9 //是否支持for循环可枚举 10 enumerables = t

Ext原码学习之lang-Object.js

// JavaScript Document (function(){ var TemplateClass = function(){}, ExtObject = Ext.Object = { chain:Object.create || function(object) { TemplateClass.prototype = object; var result = new TemplateClass(); TemplateClass.prototype = null; return resu

Ext原码学习之Ext-more.js

// JavaScript Document Ext.apply(Ext,{ userAgent:navigator.userAgent.toLowerCase(), cache:{}, isSeed:1000, windowId:'ext-window', documentId:'ext-document', isReady:false, enableGarbageCollector:true, enableListenerCollection:true, rootHierarchyState

Java源码学习 -- java.lang.StringBuilder,java.lang.StringBuffer,java.lang.AbstractStringBuilder

一直以来,都是看到网上说“ StringBuilder是线程不安全的,但运行效率高:StringBuffer 是线程安全的,但运行效率低”,然后默默记住:一个是线程安全.一个线程不安全,但对内在原因并不了解.这两天终于下定决心看了下源代码,才深刻理解为啥一个线程安全.一个非线程安全. 一名话总结:java.lang.StringBuilder 与 java.lang.StringBuffer 同是继承于 java.lang.AbstractStringBuilder,具体在功能实现大多在 Abs

观V8源码中的array.js,解析 Array.prototype.slice为什么能将类数组对象转为真正的数组?

在官方的解释中,如[mdn] The slice() method returns a shallow copy of a portion of an array into a new array object. 简单的说就是根据参数,返回数组的一部分的copy.所以了解其内部实现才能确定它是如何工作的.所以查看V8源码中的Array.js     可以看到如下的代码: 一.方法  ArraySlice,源码地址,直接添加到Array.prototype上的"入口",内部经过参数.类型

【 js 基础 】【 源码学习 】源码设计 (持续更新)

学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:underscore 设计分析 第一部分: zepto 设计分析zepto 是一个轻量级的 Javascript 库.相对于 jquery 来说在 size 上更加小,主要是定位于移动设备.它是非常好的学习源码的入门级 javascript 库.这里重点说一下,这个库的设计,而对于详细的源码学习大家可以 star

【 js 基础 】【 源码学习 】柯里化和箭头函数

最近在看 redux 的源码,代码结构很简单,主要就是6个文件,其中 index.js 负责将剩余5个文件中定义的方法 export 出来,其他5个文件各自负责一个方法的实现. 大部分代码比较简单,很容易看懂,但是在 applyMiddleware.js 中 有一个地方还是很有意思,用到了柯里化和箭头函数的组合.由于增强 store,丰富 dispath 方法的时候,可能会用到多个 中间件,所以这个的嵌套有可能会很深,导致对 箭头函数和柯里化 不是很熟悉的童鞋,一看源码就会有些理不清思路. 一.

??px4原生源码学习(1/3)-----为什么没main函数!!!!!

本文转自px4原生源码学习-(2)--实时操作系统篇 * 为什么我要谈到实时操作系统? 如果你只是开发一个简简单单的单片机程序,不用考虑以后对于程序的升级与修改,那么你简简单单写个main函数的while循环其实没什么不好.但你要遇到那种开发周期长,系统复杂的产品或者项目,那最好是基于实时操作系统开发.因为这对于代码重用和添加新功能或者新设备来说会方便挺很多,代码的编写程度也会简单很多.像早期的apm飞控也是基于板子的main函数,导致其代码复杂,冗余,后面直接被弃,因为可能每添加一个功能或者设

原码,反码和补码学习报告

放假这几天,重新学习了原码反码和补码的相关知识.对原码反码和补码有了重新的认识.所以写了这篇博客,作以总结. 学习原码反码补码时主要是看了叶子秋前辈的博客(http://www.cnblogs.com/zhangziqiu/ ).对于原码反码补码的知识写的非常详细,也引用了很多例子.通过前辈的博客,了解到一个叫做机器数的东西,就是我们常用的二进制数,比如在8位二进制中,数字1的机器数就是00000001.通过真值,明白一长串二进制符并不完全代表数字.开头的01表示这个·数据的正负. 原码,就是符