Ecmascript 标准中的Array.prototype中的函数定义
来源:互联网 发布:js获取被选中的radio 编辑:程序博客网 时间:2024/05/16 15:49
大家都知道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.prototype.toString = function(){ //需要的属性 join var 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; // toObject var 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 E = items.shift(); //标准里写的不是shift函数实现这个,后面相同 if(E instanceof Array){ 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; // toObject var lenVal = O.length; var len = lenVal; //toUint32 sepatator = 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;};Array.prototype.pop = function (){ var O = this; // toObject var 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;};Array.prototype.push = function(item1) { var O = this ; //toObject var 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;};Array.prototype.reverse = function () { var O = this; //toObject var lenVal = O.length; var len = lenVal; // toUint32 var middle = Math.floor(len/2); var lower = 0; while(lower !== middle){ //不知道为什么标准里写的不是 lower >= middle var 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;};Array.prototype.shift = function (){ var O = this; //toObject var lenVal = O.length; var len = lenVal; // toUint32 if(len === 0) { O.length = 0; return undefined; } 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;};Array.prototype.slice = function (start, end){ var O = this; //toObject var A = []; var lenVal = O.length; var len = lenVal; // toUint32 var relativeStart = start; // toIntger var 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 (){};Array.prototype.splice = function (start,deleteCount) { var O = this; //toObject var A = []; var lenVal = O.length; var len = lenVal; // toUint32 var relatveStart = start; // toIntger var 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;};Array.prototype.unshift = function (item1){ var O = this; //toObject var lenVal = O.length; var len = lenVal; // toUint32 var 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;};Array.prototype.indexOf = function (searchElement){ var O = this; //toObject var lenVal = O.length; var len = lenVal; // toUint32 if(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;};Array.prototype.lastIndexOf = function (searchElement){ var O = this; var lenVal = O.length; var len = lenVal; // toUint32 if(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;};Array.prototype.every = function (callbackfn){ var O = this; //toObject var lenVal = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} var 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;};Array.prototype.some = function (callbackfn){ var O = this; //toObject var lenVal = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} var 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;};Array.prototype.forEach = function(callbackfn){ var O = this; //toObject var lenValue = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} var 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;};Array.prototype.map = function(callbackfn){ var O = this; //toObject var lenValue = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} var 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;};Array.prototype.filter = function(callbackfn){ var O = this; //toObject var lenValue = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} var 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;};Array.prototype.reduce = function (callbackfn){ var O = this; //toObject var lenValue = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} //if(len === 0 && arguments.length < 2 ) {throw "type error"} var 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;};Array.prototype.reduceRight = function (callbackfn){ var O = this; //toObject var lenValue = O.length; var len = lenVal; // toUint32 //if(! callbackfn instanceof Function) {throw "typeerror"} //if(len === 0 && arguments.length < 2 ) {throw "type error"} var 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;};
0 0
- Ecmascript 标准中的Array.prototype中的函数定义
- ES5 中的Array.prototype.reduce( )方法
- 标准C++中的类型定义
- Swift中的标准函数
- Swift2中的标准函数
- javascript 对象中的函数 定义方式用prototype 动态增添 节省空间
- ECMAScript中的Object类
- ECMAScript中的String类
- ECMAScript中的Function
- ECMAScript中的数组
- ECMAScript中的Undefined类型
- ECMAScript中的Uull类型
- ECMAScript中的Boolean类型
- ECMAScript中的Nnmber类型
- ECMAScript中的String类型
- ECMAscript中的数组属性
- QML中的ECMAscript
- ECMAScript中的object
- 闲聊DTD语法
- play验证码模块的实现
- Reverse Integer
- HDU 3974 Assign the task [并查集扩展]
- sqoop数据导出导入命令
- Ecmascript 标准中的Array.prototype中的函数定义
- HDU ACM 2111 Saving HDU->贪心
- oracle用户目录误删除的恢复
- Java基础:多线程
- C Primer Plus 第十章学习总结……2015.4.30
- hive over hbase方式将文本库数据导入hbase
- 初体验
- 存储器问题
- 使用FileFilter过滤文件清理Maven仓库