切片,js:我也行

2,521 阅读2分钟
原文链接: zhuanlan.zhihu.com

熟悉python的,都知道python中的切片能大大简化操作,回头望一望js中的切片家族,还是有一两个的,slice,splice,substr,substring等等,不乏有人,有了基础支持,剩下的事就好办了。

[: :]操作符

基于JavaScript的语法,如果你这么写,那么你就试试吧, (;¬_¬) ,这里我们采用函数的方式来实现切片效果。

直接上代码(数组)

if (!Array.prototype.select) {
	    Object.defineProperty(Array.prototype, 'select', {
	        value: function(item) {
	            'use strict';
	            if (this == null) {
	                throw new TypeError('Array.prototype.select called on null or undefined');
	            }
	            if (!Array.isArray(this)) {//this必须是Array类型
	                throw new TypeError('This Object is not Array');
	            }
	            var arr = [];
	            var i = arguments[0] || 0;//起始位置
	            var len = this.length >>> 0;//数组的长度
	            var end = len;//结束位置
	            if (!arguments[1]) {
	                if (arguments[1] === 0){//解决结束位置是0的情况
	                    end = 0;
	                }
	            }else{
	                end = Math.min(Math.abs(arguments[1]), len);
	                //当结束位置过长就设置为数组的结束位置
	            }
	            end = end >= 0 ? end : len + end;//结束位置是负数的情况
	            var step = arguments[2] || 1;//默认连续取值
	            step = Math.abs(step);
	            if (arguments[2] < 0){//倒叙取值
	                for (i = end - 1; i >= 0; i = i - step){
	                    arr.push(this[i]);
	                }
	            }else {
	                for (i; i < end; i = i + step){
	                    arr.push(this[i]);
	                }
	            }
	            return arr;
	        },
	        configurable: true,
	        enumerable: false,
	        writable: true,
	    });
}

关于数组的判断

if (!Array.isArray) {
    Object.defineProperty(Array, 'isArray', {
        value: function(arg) {
            return Object.prototype.toString.call(arg) === '[object Array]';
        },
        configurable: true,
        enumerable: false,
        writable: true
    });
}

字符串的切片

if (!String.prototype.select) {
	    Object.defineProperty(String.prototype, 'select', {
	        value: function(item) {
	            'use strict';
	            if (this == null) {
	                throw new TypeError('String.prototype.select called on null or undefined');
	            }
	            if (typeof this !== "string") {
	            	throw new TypeError('This Object is not String');
	            }
	            var arr = [];
	            var i = arguments[0] || 0;//起始位置
	            var len = this.length >>> 0;//数组的长度
	            var end = len;//结束位置
	            if (!arguments[1]) {
	                if (arguments[1] === 0){//解决结束位置是0的情况
	                    end = 0;
	                }
	            }else{
	                end = Math.min(Math.abs(arguments[1]), len);
	                //当结束位置过长就设置为数组的结束位置
	            }
	            end = end >= 0 ? end : len + end;//结束位置是负数的情况
	            var step = arguments[2] || 1;//默认连续取值
	            step = Math.abs(step);
	            if (arguments[2] < 0){//倒叙取值
	                for (i = end - 1; i >= 0; i = i - step){
	                    arr.push(this[i]);
	                }
	            }else {
	                for (i; i < end; i = i + step){
	                    arr.push(this[i]);
	                }
	            }
	            return arr.join('');
	        },
	        configurable: true,
	        enumerable: false,
	        writable: true,
	    });
}

测试一下

var arr = [1,2,3,4,5,6,7,8,9];
console.log(arr.select(1,-1,2));
console.log(arr.select(1,-1,-2));
显示结果
性能对比,还是原生的好呀

源码: 切片操作,以及一些别的数组操作