设置JavaScript对象的长度属性

时间:2011-06-20 14:14:34

标签: javascript

假设我有一个JavaScript对象:

function a(){
    var A = [];
    this.length = function(){
        return A.length;
    };
    this.add = function(x){
        A.push(x);
    };
    this.remove = function(){
        return A.pop();
    };
};

我可以像这样使用它:

var x = new a();
x.add(3);
x.add(4);
alert(x.length()); // 2
alert(x.remove()); // 4
alert(x.length()); // 1

我试图让.length不是一个函数,所以我可以像这样访问它:x.length,但我没有运气让它发挥作用。

我尝试了这一点,但它会输出0,因为那是A的长度:

function a(){
    var A = [];
    this.length = A.length;
    //rest of the function...
};

我也试过这个,它也输出了0

function a(){
    var A = [];
    this.length = function(){
        return A.length;
    }();
    //rest of the function...
};

如何让x.length在对象中输出正确的数组长度?

7 个答案:

答案 0 :(得分:5)

您可以使用valueOf hack

this.length = {
    'valueOf': function (){
        return A.length;
    },
    'toString': function (){
        return A.length;
    }
};

现在您可以访问x.length的长度。 (虽然,也许只是我,但对我而言,这个方法的一些东西感觉非常迂回,并且很容易使用更坚固的解决方案,例如,在每次修改后更新长度属性。)

答案 1 :(得分:3)

如果您希望A保持'私密',则需要在每次修改length长度的操作上更新公共A属性,以便您不需要要求时检查的方法。我会通过'私人'方法这样做。

<强>代码:

var a = function(){
    var instance, A, updateLength;

    instance = this;
    A = [];
    this.length = 0;

    updateLength = function()
    {
      instance.length = A.length;
    }

    this.add = function(x){
        A.push(x);
        updateLength();
    };

    this.remove = function(){
        var popped = A.pop();
        updateLength();

        return popped;
    };
};

<强>演示: http://jsfiddle.net/JAAulde/VT4bb/

答案 2 :(得分:2)

因为当你致电a.length时,你正在返回一个功能。为了返回输出,你必须实际调用函数,即:a.length()

顺便说一句,如果你不想让length属性成为函数而是实际值,你需要修改你的对象以返回属性。

function a() {
  var A = [];
  this.length = 0;
  this.add = function(x) {
    A.push(x);
    this.length = A.length;
  };
  this.remove = function() {
    var removed = A.pop();
    this.length = A.length;
    return removed;
  };
};

答案 3 :(得分:1)

虽然每个人都说的是关于ES3的,但是这个长度必须是一个函数(否则它的值将保持静态,除非你以其他方式破解它),你可以在ES5中拥有你想要的东西(在chrome中试试这个示例):

function a(){
    var A = [],
        newA = {
         get length(){ return A.length;}
        };
    newA.add = function(x){
        A.push(x);
    };
    newA.remove = function(){
        return A.pop();
    };
    return newA;
}

var x = a();
x.add(3);
x.add(4);
alert(x.length); // 2
alert(x.remove()); // 4
alert(x.length); // 1

你应该使用Object.create而不是函数a,虽然我把它作为一个看起来像你原来的函数。

答案 4 :(得分:0)

我不认为你可以作为变量访问它作为变量我的知识无法返回方法的值,除非你将劫持数组对象并在推/弹时更新你的变量方法被称为(丑陋!)。为了使您的方法版本有效,我认为您应该执行以下操作:

function a(){
    this.A = [];
    this.length = function(){
        return this.A.length;
    };
    this.add = function(x){
        this.A.push(x);
    };
    this.remove = function(){
        return this.A.pop();
    };
};

答案 5 :(得分:0)

这几天,您可以使用defineProperty

let x = {}

Object.defineProperty(x, 'length', {
  get() {
    return Object.keys(this).length
  },
})

x.length // 0
x.foo = 'bar'
x.length // 1

或者在您的特定情况下:

Object.defineProperty(x, 'length', {
  get() {
    return A.length
  }
})

答案 6 :(得分:-1)

function a(){
    this.A = [];
    this.length = function(){
        return this.A.length;
    };
    this.add = function(x){
        this.A.push(x);
    };
    this.remove = function(){
        return this.A.pop();
    };
};