Reference to slice of an array

岁酱吖の 提交于 2019-12-04 11:51:48

I don't think you can do this with native JS arrays (well, not in a straightforward manner anyway).

I think the cleanest approach would be going back and using custom objects to represent the slices. Perhaps something along these lines:

function ArraySlice(arr, lo, hi){
    this.arr = arr;
    this.lo = lo;
    this.hi = hi;
    this.length = hi - lo;
};
ArraySlice.prototype._contains = function(ix){
    return this.lo + ix < this.hi;
};
ArraySlice.prototype.get = function(ix){
    if (this._contains(ix)){
        return this.arr[this.lo + ix];
    }else{
        return; //undefined
    }
};
ArraySlice.prototype.set = function(ix, value){
    if (this._contains(ix)){
        return (this.arr[this.lo + ix] = value);
    }else{
        return; //undefined
    }
};

var a = [0,1,2,3,4,5];
var b = new ArraySlice(a, 1, 3);

a[2] = 17;
console.log( b.get(1) );

Of course, this loses the convenient [] syntax and the objects aren't arrays anymore but subclassing Array is annoying and error prone and I don't believe there is a cross-browser way to do operator overloading.

slice() copies elements to a new array.

So, in your example, A and B are two completely different arrays. So, changing elements in one does not affect another.

Here is the only possible solution I see:

  • extend Array class and store all array data in a singleton class instance
  • create a unique identifier (UID) when you first create a new array
  • use that identifier when you are trying to get data from singleton
  • use that same identifier when you're making a slice

This may however break lots of your code.

I'm pretty sure this isn't possible in Javascript. This line var B = A.mySlice(1,5); sets B to an array object containting a slice of A's numbers. It has no reference to A. It's just an array object.

It's not quite as clean, since you'd be dealing with function objects, but you could wrap the calls to chain back up the original array using closures:

var A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
A.mySlice = function (l, h) { return function() { return this.slice(l, h); }; };

var B = A.mySlice(1, 5); // B() will resolve to ["b", "c", "d", "e"]
B.mySlice = function (l, h) { return function() { return this().slice(1, h) }; };

A[3] = 33;
A.mySlice(1, 5)() // ["b", "c", 33, "e"]
B.mySlice(0, 3)() // ["b", "c", 33]
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!