我想要实现的是在 JavaScript 中创建一些对对象属性进行操作的函数,这是相当典型的事情。
问题是出于灵活性和可扩展性的考虑,我不希望函数提前知道对象。据我所知,这正是 Javascript 应该非常擅长的事情,但是没有花很多时间在函数式语言上,我还没有掌握如何去做。
所以我可能会遇到这样的情况:
function Owner()
{
var self=this;
self.size = 100;
self.writers = [];
}
function Writers()
{
var Alice= function()
{
var that=this;
that.name="alice";
that.operate = function()
{
console.log( "Alice says: "+self.size );
}
}
this.alice=new Alice();
}
var owner = new Owner();
var writers = new Writers();
owner.writers.push( writers.alice );
owner.writers[0].operate();
现在,这Alice Says: undefined
一切都很好,但并不完全是我想要的——我显然希望看到Alice Says: 100
。在经典语言中,我可能不得不向 Alice 函数提供对所有者的引用(在伪 C# 中):
public class Owner()
{
private List<Writer> writers;
public Owner()
{
this.size=100;
this.writers= List<Writer>();
}
public int Size{ get; set; }
public void AddWriter( Writer writer )
{
writer.Owner = this;
this.writers.Add(writer);
}
}
public class Writer
{
private Owner owner;
private string name;
public void Writer( string name )
{
this.name=name;
}
public void operate()
{
Console.WriteLine( "{0} says: {1}", name, owner.Size );
}
}
据我所知,这不是非常 Javascripty - 似乎应该有更好的 - 或者至少更惯用的 - 这样做的方式。
就我正在使用的代码的实际目标而言(基本上是这样,但更复杂),目标是能够添加任意数量的“Writer”类,这些类可以对“Owner”实例执行操作以它们是附加的。这基本上是该Decorator
模式的一种实现,我可以想出很多方法来实现它,但正如我所说,我正在寻找了解 Javascript 的功能/原型性质如何在这种情况下帮助我,所以我可以更好地掌握语言。
我也不完全满意我通过实例传递函数的方式——我觉得我应该能够像五彩纸屑一样在周围扔函数,所以任何关于如何与变量范围交互的提示都会非常有帮助。
如果事实证明我正在尝试做的是倒退,并且有更好的方法来实现这种目标,那也很好。我正在尝试在 Javascript 中使用好的语言,但事实证明这很棘手,但我学到了很多东西。
编辑:我的目标是有一个基本类型,我在设计它时不必知道它可能必须执行的操作的完整列表,并且我不必为每个不同的可用组合创建一个新的子类操作,确保我的操作与我的核心类型分离。
因此,如果我有一个Animal
类型,然后我的操作是Eat
,等等,理想情况下我会进行Run
类型调用(我意识到这有点像,但我假设这些操作属于特定的基本类型)通知我该操作是否可用,然后告诉我是否可以访问。当动作被调用时,它会影响父对象的属性。在它的生命周期中,可能会在任何时候添加或删除能力,但只要检查它是否做了足以满足我需要的事情。Grow
myAnimal.can("Eat")
hasOwnProperty
myAnimal.actions.Eat("leaves")
Eat
myAnimal
myAnimal
can