Ecmascript 标准中的Array.prototype中的函数定义

大家都知道javascript中的 call 和 apply 是很有用的。不懂的自行百度。 看到别人用内置的函数处理一个自定义的对象我们都会感到非常的崇拜。比如 删除obj 中前五个和后五个数据[].slice.call(obj,5,-5)。对于Array的原型中的函数(不限于Array),Ecmascript标准中也是有这样的描述:

xxx 函数被有意设计成通用的;它的 this 值并非必须是数组对象。因此,它可以作为方法转移到其他类型的对象中。一个宿主对象是否可以正确应用这个 splice 函数是依赖于实现的。

我们疑惑的是一个对象具有什么样的属性才可以调用一些内置的函数呢。这个就需要我们去查阅Ecmascript 协议标准,可是大家都懂得,标准写的还是很有技术水平的,不是一时半会儿可以看得懂的。 所以我就根据Ecmascript的标准写出了Array.prototype(目前只写了这个,以后补充)中函数近似等价的javascript函数,当然并不能完全等价,可是大部分还是尽量贴近原始函数的实现。当然只能贴近有些功能是不能用javascript中语句实现的。 结果你会发现,其实一个对象基本是只要有 length属性就可以使用这个对象作为 Array.prototype 中函数的this执行而不出错,而且 length 属性不必非要是数字。只要可以转换成整型就可以。 另一点就是可以让大家知道一个功能的具体作用,没有什么比计算机语言更严谨的描述了。 未经测试,难免有所疏漏,请大家予以指正。

Array.prototype.constructor = Array;array = this; // toObject 后面这样的注释都表示强制类型转换var func = array.join;// if (! func instanceof Function) {throw “type Error”}return func.call(array);};Array.prototype.concat = function (item1){var O = this; // toObjectvar A = []; var n = 0;var items = [O];var i;for(i = 0; i < arguments.length; i++) {items.push(arguments[i]); // 标准里没有使用push实现这个,只是为了表达标准里的意思,后面相同}while(items.length){){var k = 0; var len = E.length;while(k < len){if(E.hasOwnPropery(k.toString())){A[n] = E[k];}n++; k++;}}else{A[n] = E;n++;}}return A;};Array.prototype.join = function(sepatator){var O = this; // toObjectvar lenVal = O.length;var len = lenVal; //toUint32sepatator = sepatator || “,”;var sep = sepatator.toString();if(len === 0) { return “”; }var element0 = O[0];var R = element0 === undefined || element0 === null ? “” : element0.toString();var k = 1;while(k < len){var S = R + sep;element = O[k];var next = element === undefined || element === null ? “” : element.toString();R = S + next;k++;}return R;};O = this; // toObjectvar lenVal = O.length;var len = lenVal; // 强制类型转换toUint32;if(len === 0){O.length = 0;return undefined;}var element = O[len-1];delete O[len-1]; //对于数组,这句可以没有,但是对于obj这是必须的O.length = len-1;return element;};O = this ; //toObjectvar lenVal = O.length;var n = lenVal; // toUint32;var items = [O];var i;for(i = 0; i < arguments.length; i++) {items.push(arguments[i]); // 标准里没有使用push实现这个}while(items.length > 0){var E = items.shift();O[n] = E;n++;}O.length = n;return n;};O = this; //toObjectvar lenVal = O.length;var len = lenVal; // toUint32var middle = Math.floor(len/2);var lower = 0;while(lower !== middle){ //不知道为什么标准里写的不是 lower >= middlevar upper = len – lower – 1;var lowerValue = O[lower];var upperValue = O[upper];if(O.hasOwnPropery(lower.toString()) && O.hasOwnPropery(upper.toString())){O[lower] = upperValue;O[upper] = lowerValue;}else if(!O.hasOwnPropery(lower.toString()) && O.hasOwnPropery(upper.toString())){O[lower] = upperValue;delete O[upper] ;}else if( O.hasOwnPropery(lower.toString()) && !O.hasOwnPropery(upper.toString()) ){delete O[lower];O[upper] = lowerValue;}lower++;}return O;};O = this; //toObjectvar lenVal = O.length;; }var first = O[0];var k =1;while(k < len){var from = k.toString();if(O.hasOwnPropery(from)){O[k-1] = O[k];}else{delete O[k-1];}k++;}delete O[k-1];O.length = len – 1;return first;};O = this; //toObjectvar A = [];var lenVal = O.length;k = relativeStart < 0 ? Math.max(len + relativeStart,0):Math.min(relativeStart,len);var relatveEnd = typeof end ===”undefined” ? len : end; // toIntger(end)var final_ = relatveEnd < 0 ? max(len+relatveEnd,0) : min(relativeEnd,len);var n = 0;while(k < final_){if(O.hasOwnPropery(k.toString())){A[n] = O[k];}k++;n++;}return A;};Array.prototype.sort = function (){};O = this; //toObjectvar A = [];var lenVal = O.length;actualStart = relatveStart < 0 ? Math.max(len + relatveStart,0): Math.min(relatveStart,len);var actualDeleteCount = Math.min(max(deleteCount,0),len – actualStart); //toIntger(deleteCount)var k = 0;var from;while(k < actualDeleteCount){from = (actualStart+k).toString();if(O.hasOwnPropery(from)){A[k] = O[actualStart+k];}k++;}var items = [];for(i = 2; i < arguments.length; i++) {items.push(arguments[i]); // 标准里没有使用push实现这个}var itemCount = items.length;if(itemCount < actualDeleteCount){k = actualStart;while(k < len – actualDeleteCount){from = (k+actualDeleteCount).toString();if(O.hasOwnPropery(from)){O[k+itemCount] = O[k+actualDeleteCount];}else{delete O[k+itemsCount];}k++;}k = len;while(k > len-actualDeleteCount + itemsCount){delete O[k-1];k–;}}else if(itemCount > actualDeleteCount){k = len – actualDeleteCount;while(k > actualStart){from = (k+actualDeleteCount – 1).toString();if(O.hasOwnPropery(from)){O[k + itemCount – 1] = O[k+actualDeleteCount -1];}else{delete O[k + itemCount -1];}k–;}}k = actualStart;while(items.length>0){var E = items.shift();O[k] = E;k++;}O.length = len – actualDeleteCount + itemCount;return A;};O = this; //toObjectvar lenVal = O.length;var len = lenVal; // toUint32var argCount = arguments.length;var k = len;while(k > 0){var from = (k-1).toString();if(O.hasOwnPropery(from)){O[k + argCount – 1] = O [k-1];}else{delete O[k + argCount -1];}k–;}var j = 0;var items = []; var i;for(i = 0 ; i < arguments.length;i++){items.push(arguments[i]);}while(items.length > 0){var E = items.shift();O[j] = E;j++;}O.length = len + argCount;return len+argCount;};O = this; //toObjectvar lenVal = O.length;var len = lenVal; // toUint32if(len === 0) { return -1; }var n = arguments.length >=2 ? arguments[1] : 0; //toIntger(arguments[1])if(n > len) { return -1; }var k = n>=0 ? n : Math.max(len + n, 0);while(k < len){if(O.hasOwnPropery(k.toString)()){if(searchElement === O[k]) {return k;}}k++;}return -1;};O = this;var lenVal = O.length;var len = lenVal; // toUint32if(len === 0) { return -1; }var n = arguments.length >=2 ? arguments[1] : 0; //toIntger(arguments[1])var k = n>=0 ? min(n,len-1) : len + n;while(k >= 0){if(O.hasOwnPropery(k.toString)()){if(searchElement === O[k]) {return k;}}k++;}return -1;};O = this; //toObjectvar lenVal = O.length;T = arguments.length >=2 ? arguments[1] : undefined;var k = 0;while(k < len){if(O.hasOwnPropery(k.toString())){var testResult = callbackfn.call(T,O[k],k,O);if(!testResult) { return false; }}k++;}return true;};O = this; //toObjectvar lenVal = O.length;T = arguments.length >=2 ? arguments[1] : undefined;var k = 0;while(k < len){if(O.hasOwnPropery(k.toString())){var testResult = callbackfn.call(T,O[k],k,O);if(testResult) { return true; }}k++;}return false;};O = this; //toObjectvar lenValue = O.length;T = arguments.length >=2 ? arguments[1] : undefined;var k = 0;while( k < len ){if(O.hasOwnPropery(k.toString())){callbackfn.call(T,O[k],k,O);}k++;}return undefined;};O = this; //toObjectvar lenValue = O.length;T = arguments.length >=2 ? arguments[1] : undefined;var A = [];var k = 0;while( k < len ){if(O.hasOwnPropery(k.toString())){A[k] = callbackfn.call(T,O[k],k,O);}k++;}return A;};O = this; //toObjectvar lenValue = O.length;T = arguments.length >=2 ? arguments[1] : undefined;var A = [];var k = 0;var to = 0;while( k < len ){if(O.hasOwnPropery(k.toString()) ){if( callbackfn.call(T,O[k],k,O) ){A[to] = O[k];to++;}}k++;}return A;};O = this; //toObjectvar lenValue = O.length;k = 0;var accumulator;if(arguments.length > 2) {accumulator = arguments[1];}else{var kPresent = false;while(kPresent === false && k < len){kPresent = O.hasOwnPropery(k.toString());if(kPresent){accumulator = O[k];}k++;}// if(!kPresent) {throw “type error”}}while( k < len ){if(O.hasOwnPropery(k.toString())){accumulator = callbackfn.call(undefined,accumulator,O[k],k,O);}k++;}return accumulator;};O = this; //toObjectvar lenValue = O.length;k = len – 1;var accumulator;if(arguments.length > 2) {accumulator = arguments[1];}else{var kPresent = false;while(kPresent === false && k >= 0){kPresent = O.hasOwnPropery(k.toString());if(kPresent){accumulator = O[k];}k–;}// if(!kPresent) {throw “type error”}}while( k >= 0 ){if(O.hasOwnPropery(k.toString())){accumulator = callbackfn.call(undefined,accumulator,O[k],k,O);}k–;}return accumulator;};

,告诉自己,我这次失败了,重新开始吧!下次我会吸取教训,不让自己犯同样的错误的

Ecmascript 标准中的Array.prototype中的函数定义

相关文章:

你感兴趣的文章:

标签云: