如何在javascript中创建数组的方法作为对象的属性?

时间:2023-02-09 23:46:18

Please consider this code in javascript:

请在javascript中考虑此代码:

function Selector() {
    this.Status = "";
    this.Groups = new Array();
    this.Errors = new Array();
}

I want to add a method for Groups property of the Selector class and use it for any instance. How can i do this?

我想为Selector类的Groups属性添加一个方法,并将其用于任何实例。我怎样才能做到这一点?

Please be aware that i write this code:

请注意我写这段代码:

function Selector() {
    this.Status = "";
    this.Groups = []; 
    this.Groups.myFunction = function(){alert(this.length);  
    };
    this.Errors = [];
}

var selector = new Selector();
selector.Groups = [1,2,3];
selector.Groups.myFunction();

But when i set Group property i get error for calling method:

但是当我设置Group属性时,我得到调用方法的错误:

Error: selector.Groups.myFunction is not a function

错误:selector.Groups.myFunction不是函数

I prefer to find a way using prototype object.

我更喜欢使用原型对象找到一种方法。

Thanks.

谢谢。

2 个解决方案

#1


1  

When you say:

当你说:

  selector.Groups = [1,2,3];
  selector.Groups.myFunction();

You are actually initializing a new array and storing it in the selector.Groups property, and since Array object does not have a method called myFunction, you get an error.

您实际上正在初始化一个新数组并将其存储在selector.Groups属性中,并且由于Array对象没有名为myFunction的方法,因此会出现错误。

You could extend the Array object so that every array has a myFunction method, like this:

您可以扩展Array对象,以便每个数组都有一个myFunction方法,如下所示:

  Array.prototype.myFunction = function() { alert(this.length) };

Which is not a good idea imo, but you're not left with many options since subclassing an array will not maintain the length property in IE :(

这不是一个好主意imo,但你没有留下很多选项,因为子类化数组将不会维持IE中的length属性:(

See this link for an iframe hack to Array subclassing.

请参阅此链接以获取iframe hack to Array子类化。

#2


1  

Your code will not work in this way, because in constructor you're assigning an object (array) to class property and extending that particular instance. Then when you're assigning new array, that newly created array has no such method. So your solution can be changed in this way:

您的代码将无法以这种方式工作,因为在构造函数中,您将对象(数组)分配给类属性并扩展该特定实例。然后,当您分配新数组时,新创建的数组没有这样的方法。因此,您可以通过以下方式更改解决方案:

function Selector() {
    this.Status = "";
    this.setGroups([]);
    this.Errors = [];
}

Selector.prototype.myFunction = function() {
    alert(this.length);
};

Selector.prototype.setGroups = function(groups) {
    this.Groups = groups;
    this.Groups.myFunction = this.myFunction;
};

var selector = new Selector();
selector.Groups.myFunction();
selector.setGroups([1,2,3]);
selector.Groups.myFunction();
selector.setGroups(['foo', 'bar']);
selector.Groups.myFunction();

DEMO

DEMO

​But I don't recommend you to use such practice though. Better is to create a class GroupCollection and encapsulate an array as its property:

但我不建议你使用这种做法。更好的是创建一个类GroupCollection并将数组封装为其属性:

function GroupCollection(items) {
    this.items = items || [];
}

GroupCollection.prototype.myFunction = function() {
    alert(this.items.length);
};

function Selector() {
    this.Status = "";
    this.Groups = new GroupCollection();
    this.Errors = [];
}

Selector.prototype.setGroups = function(groups) {
    this.Groups.items = groups;
};

var selector = new Selector();
selector.Groups.myFunction();
selector.setGroups([1,2,3]);
selector.Groups.myFunction();
selector.setGroups(['foo', 'bar']);
selector.Groups.myFunction();

DEMO

DEMO

#1


1  

When you say:

当你说:

  selector.Groups = [1,2,3];
  selector.Groups.myFunction();

You are actually initializing a new array and storing it in the selector.Groups property, and since Array object does not have a method called myFunction, you get an error.

您实际上正在初始化一个新数组并将其存储在selector.Groups属性中,并且由于Array对象没有名为myFunction的方法,因此会出现错误。

You could extend the Array object so that every array has a myFunction method, like this:

您可以扩展Array对象,以便每个数组都有一个myFunction方法,如下所示:

  Array.prototype.myFunction = function() { alert(this.length) };

Which is not a good idea imo, but you're not left with many options since subclassing an array will not maintain the length property in IE :(

这不是一个好主意imo,但你没有留下很多选项,因为子类化数组将不会维持IE中的length属性:(

See this link for an iframe hack to Array subclassing.

请参阅此链接以获取iframe hack to Array子类化。

#2


1  

Your code will not work in this way, because in constructor you're assigning an object (array) to class property and extending that particular instance. Then when you're assigning new array, that newly created array has no such method. So your solution can be changed in this way:

您的代码将无法以这种方式工作,因为在构造函数中,您将对象(数组)分配给类属性并扩展该特定实例。然后,当您分配新数组时,新创建的数组没有这样的方法。因此,您可以通过以下方式更改解决方案:

function Selector() {
    this.Status = "";
    this.setGroups([]);
    this.Errors = [];
}

Selector.prototype.myFunction = function() {
    alert(this.length);
};

Selector.prototype.setGroups = function(groups) {
    this.Groups = groups;
    this.Groups.myFunction = this.myFunction;
};

var selector = new Selector();
selector.Groups.myFunction();
selector.setGroups([1,2,3]);
selector.Groups.myFunction();
selector.setGroups(['foo', 'bar']);
selector.Groups.myFunction();

DEMO

DEMO

​But I don't recommend you to use such practice though. Better is to create a class GroupCollection and encapsulate an array as its property:

但我不建议你使用这种做法。更好的是创建一个类GroupCollection并将数组封装为其属性:

function GroupCollection(items) {
    this.items = items || [];
}

GroupCollection.prototype.myFunction = function() {
    alert(this.items.length);
};

function Selector() {
    this.Status = "";
    this.Groups = new GroupCollection();
    this.Errors = [];
}

Selector.prototype.setGroups = function(groups) {
    this.Groups.items = groups;
};

var selector = new Selector();
selector.Groups.myFunction();
selector.setGroups([1,2,3]);
selector.Groups.myFunction();
selector.setGroups(['foo', 'bar']);
selector.Groups.myFunction();

DEMO

DEMO