Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript数组上的Getter/setter?_Javascript_Arrays_Setter_Getter - Fatal编程技术网

javascript数组上的Getter/setter?

javascript数组上的Getter/setter?,javascript,arrays,setter,getter,Javascript,Arrays,Setter,Getter,有没有一种方法可以获取数组的get/set行为?我想象这样的情况: var arr = ['one', 'two', 'three']; var _arr = new Array(); for (var i = 0; i < arr.length; i++) { arr[i].__defineGetter__('value', function (index) { //Do something return _arr

有没有一种方法可以获取数组的get/set行为?我想象这样的情况:

var arr = ['one', 'two', 'three'];
var _arr = new Array();

for (var i = 0; i < arr.length; i++) {
    arr[i].__defineGetter__('value',
        function (index) {
            //Do something
            return _arr[index];
        });
    arr[i].__defineSetter__('value',
        function (index, val) {
            //Do something
            _arr[index] = val;
        });
}
var-arr=['1','2','3'];
var_arr=新数组();
对于(变量i=0;i
您可以将任何方法添加到
数组中,方法是将它们添加到
数组。prototype
。下面是一个添加getter和setter的示例

Array.prototype.get = function(index) {
  return this[index];
}

Array.prototype.set = function(index, value) {
  this[index] = value;
}

为什么不为内部对象创建一个新类呢

var a = new Car();

function Car()
{
   // here create the setters or getters necessary
}
然后呢,

arr = new Array[a, new Car()]

我想你明白了。

数组访问与普通属性访问没有什么不同
array[0]
表示
array['0']
,因此您可以定义名为
'0'
的属性,并通过该属性拦截对第一个数组项的访问

但是,这确实使它不适用于除了短的、或多或少固定长度的阵列之外的所有阵列。您不能一次定义“所有恰好是整数的名称”的属性。

我希望它能有所帮助

Object.extend(Array.prototype, {
    _each: function(iterator) {
                    for (var i = 0; i < this.length; i++)
                    iterator(this[i]);
                },
    clear: function() {
                    this.length = 0;
                    return this;
                },
    first: function() {
                    return this[0];
                },
    last: function() {
                return this[this.length - 1];
                },
    compact: function() {
        return this.select(function(value) {
                                                return value != undefined || value != null;
                                                }
                                            );
        },
    flatten: function() {
            return this.inject([], function(array, value) {
                    return array.concat(value.constructor == Array ?
                        value.flatten() : [value]);
                    }
            );
        },
    without: function() {
        var values = $A(arguments);
                return this.select(function(value) {
                        return !values.include(value);
                }
            );
    },
    indexOf: function(object) {
        for (var i = 0; i < this.length; i++)
        if (this[i] == object) return i;
        return -1;
    },
    reverse: function(inline) {
            return (inline !== false ? this : this.toArray())._reverse();
        },
    shift: function() {
        var result = this[0];
        for (var i = 0; i < this.length - 1; i++)
        this[i] = this[i + 1];
        this.length--;
        return result;
    },
    inspect: function() {
            return '[' + this.map(Object.inspect).join(', ') + ']';
        }
    }
);
Object.extend(Array.prototype{
_each:函数(迭代器){
for(var i=0;i
我查阅了John Resig的文章,但他的原型示例对我不起作用。在尝试了一些替代方案后,我找到了一个似乎有效的方案。您可以按以下方式使用
Array.prototype.\uu\u defineGetter\uu

Array.prototype.__defineGetter__("sum", function sum(){
var r = 0, a = this, i = a.length - 1;
do {
    r += a[i];
    i -= 1;
} while (i >= 0);
return r;
});
var asdf = [1, 2, 3, 4];
asdf.sum; //returns 10

在Chrome和Firefox中为我工作。

可以为数组的每个元素创建setter,但有一个限制:无法直接为初始化区域之外的索引设置数组元素(例如,
myArray[2]=…//如果myArray.length<2
,则无法工作)使用Array.prototype函数将起作用。(例如推、弹出、拼接、移位、取消移位)我举了一个例子说明如何实现这一点。

这是我做事的方式。您必须调整原型创建(我从版本中删除了一点)。但这将为您提供默认的getter/setter行为,我在其他基于类的语言中已经习惯了这种行为。 定义Getter和no Setter意味着将忽略对元素的写入

希望这有帮助

function Game () {
  var that = this;
  this._levels = [[1,2,3],[2,3,4],[4,5,6]];

  var self = {
    levels: [],
    get levels () {
        return that._levels;
    },
    setLevels: function(what) {
        that._levels = what;
        // do stuff here with
        // that._levels
    }
  };
  Object.freeze(self.levels);
  return self;
}
这为我提供了以下预期行为:

var g = new Game()
g.levels
/// --> [[1,2,3],[2,3,4],[4,5,6]]
g.levels[0]
/// --> [1,2,3]
接受德瓦尔德曼的批评:写作现在应该是不可能的了。 我将代码重写为1)不使用去种族化元素(_uuu定义者)和2)不接受对levels元素的任何写入(即:非受控写入)。包括一个示例设置器。(由于降价,我不得不在_uu_uuu_uuu_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuueGetter中添加间距)

从dmvaldmans请求:

g.levels[0] = [2,3,4];
g.levels;
/// --> [[1,2,3],[2,3,4],[4,5,6]]

//using setter
g.setLevels([g.levels, g.levels, 1,2,3,[9]]);
g.levels;
/// --> [[[1,2,3],[2,3,4],[4,5,6]],[[1,2,3],[2,3,4],[4,5,6]], ....]

//using setLevels
g.setLevels([2,3,4]);
g.levels;
/// --> [2,3,4]
使用,可以获得所需的行为:

var\u arr=['1','2','3'];
var-accessCount=0;
函数doSomething(){
accessCount++;
}
var arr=新代理服务器(_arr{
get:函数(目标、名称){
doSomething();
返回目标[名称];
}
});
函数打印(值){
document.querySelector('pre').textContent+=value+'\n';
}
打印(访问计数);//0
打印(arr[0]);/'某人的
打印(arr[1]);/'两尺
打印(访问计数);//2.
打印(arr.length);//3.
打印(访问计数);//3.
打印(arr.constructor);/'函数数组(){[native code]}'

可以为JavaScript数组定义getter和setter。但不能同时拥有访问器和值。请参阅Mozilla:

不可能同时将一个getter绑定到一个属性并让该属性实际持有一个值

因此,如果为数组定义访问器,则需要为实际值定义第二个数组。下面说明了这一点

var _arr = ['one', 'two', 'three'];

var accessCount = 0;

function doSomething() {
  accessCount++;
}

var arr = new Proxy(_arr, {
  get: function(target, name) {
    doSomething();
    return target[name];
  },
  set: function(target, name, val) { doSomething(); target[name] = val; }
});

function print(value) {
  document.querySelector('pre').textContent += value + '\n';
}

print(accessCount);      // 0
print(arr[0]);           // 'one'
print(accessCount);      // 1
arr[1] = 10;
print(accessCount);      // 2
print(arr[1]);           // 10
该代码使用三个数组:

  • 一个代表实际值
  • 一个用于JSON编码的值
  • 一个用于访问者
  • 带有访问器的数组将返回给调用方。当通过向数组元素赋值来调用
    集合时,包含普通值和编码值的数组将被更新。调用
    get
    时,它只返回普通值。和
    toString
    返回包含编码值的整个查询

    但作为
    var _arr = ['one', 'two', 'three'];
    
    var accessCount = 0;
    
    function doSomething() {
      accessCount++;
    }
    
    var arr = new Proxy(_arr, {
      get: function(target, name) {
        doSomething();
        return target[name];
      },
      set: function(target, name, val) { doSomething(); target[name] = val; }
    });
    
    function print(value) {
      document.querySelector('pre').textContent += value + '\n';
    }
    
    print(accessCount);      // 0
    print(arr[0]);           // 'one'
    print(accessCount);      // 1
    arr[1] = 10;
    print(accessCount);      // 2
    print(arr[1]);           // 10