1

我开始学习 JavaScript,经过多年使用它却不知道发生了什么,我决定是时候做点什么了。此外,我在一个项目中工作,其中 JavaScript 可用于编写应用程序脚本。

所以,够了所有的 yada-yada,我的问题与原型继承有关,我我现在知道它是如何工作的,但可能存在问题。基本思想是每个对象(嗯,不是每个对象 - 是的 ;-))都有一个原型,如果实际对象在到达原型链的末端之前无法处理它,则所有请求都被委托给该原型(一个对象也可以有原型,对吧?)。

在我的应用程序中,将发生大规模过滤,我想为用户(技术性不是很强,应该尽可能简单)提供一种链接简单过滤器命令的方法,从而在每次额外调用时缩小结果集。我是什么意思?嗯。像这样:

zoo.getAnimals().getAnimalsWithFurColor("red").getMammals()

zoo始终在范围内,是一个包含动物和动物园附加属性的对象。所以,我会有一个像这样的对象(让我们调用它Container)由示例中的所有方法调用返回:

 {
   data: [harryTheElephant, sallyThePenguin, timTheWoodpecker],
   someFilterMethod: function() {
        return new Container(data.filter(function(animal) {
            return animal.someProperty == someValue;
        });
   }
 }

到现在为止还挺好。但我也希望动物园成为一个容器。这是我真正的问题发挥作用的地方:由于动物园必须做一些非常昂贵的事情来检索起始动物集,我想延迟加载它们。当动物园收到getAnimals() 请求时,将获取数据。

我的想法是将动物园的原型设置为从动物园获取数据的容器。但是我找不到getAnimals()从原型(容器)访问动物园方法的方法。我试过了,this但找不到方法。

任何想法如何编写代码来做我想做的事?请注意,我不在浏览器环境中,我在我的应用程序中嵌入了 JavaScript (1.7)。

谢谢!

4

2 回答 2

1

对象访问(原型上)从它继承的东西的属性没有多大意义。例如,如果 aCat有一个meow()方法,那么Mammal引用会很奇怪meow()。同样,Container如果getAnimals()ZooContainer.

为了完成延迟加载,我的建议是将返回数组的访问器函数传递给Container构造函数,而不是直接传递数组。这可能看起来像:

function Container(getAnimals) {
    this.someFilterMethod = function () {
        return new Container(function () {
            return getAnimals().filter(function (animal) {
                 return animal.someProperty === someValue;
            });
        });
    };

    this.get = getAnimals;
}

function makeZoo(animals) {
    var zoo = Object.create(new Container(function () { return animals; }));
    zoo.customZooMethod = function () { /* ... */ };

    return zoo;
}

var aZoo = makeZoo([harryTheElephant, sallyThePenguin, timTheWoodpecker]);
var filteredAnimals = aZoo.someFilterMethod().get();
于 2011-08-22T13:38:31.183 回答
0

对象继承自它们的内部原型,而不是它们的公共原型。

要实现链接,只需让每个方法返回实例。

例如

function Foo(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
} 

Foo.prototype.sayFirstName = function() {
  alert(this.firstName);
  return this;
}

Foo.prototype.sayLastName = function() {
  alert(this.lastName);
  return this;
}

var foo = new Foo('Foo', 'Bar');

foo.sayFirstName().sayLastName();

但是,链接不是一个好主意,因为它使调试变得困难。如果您将一堆命令链接在一起并在单个语句或表达式中并且它失败了,那么您如何找出哪个失败了?

编辑

您可能想要执行以下操作:

// Container constructor
function Container(dataArray) {
  this.data = dataArray;
}

// Filter data and return new container
Container.prototype.getAnimalsWithFurColor = function(color) {
  var filteredArray = [];

  for (var i=0, iLen=this.data.length; i<iLen; i++) {

    // Presuming the items (animals?) in data have a getColor methed 
    if (this.data[i].getColor() == color) {
      filteredArray.push(this.data[i]);
    }
  }
  return new Container(filteredArray);
}
于 2011-08-22T13:12:45.710 回答