2016-12-27 64 views
0

我有这个简单的类:在构造函数之前运行链接方法?

class Foo { 
 
    constructor() { 
 
    this.init(); 
 
    return this; 
 
    } 
 

 
    init() { 
 
    this.onInit(); 
 
    } 
 

 
    onInit(callback) { 
 
    this.onInit =() => callback(); 
 
    return this; 
 
    } 
 
} 
 

 
new Foo().onInit(() => console.log('baz'));

这显然是有缺陷的,因为它会调用initonInit方法能够定义onInit属性/回调。

如何在不改变界面的情况下使这项工作成为可能?

+2

如果将“init”定义为“当构造函数正在执行时”,那么将回调设置为构造函数的链接事件(根据定义在*构造函数后执行*)是简单的矛盾,并且没有合理的解决方法那。 – deceze

+0

我明白了你的观点,事实是我的库是'new Something()。onCreate()。onUpdate()',它是有道理的,因为它创建了实例,然后在实例之后设置你想要做的事情已创建(以及何时更新)。所以,“语法”,这是有道理的,我想找到一种方法来保持它.. –

+1

*语法*如果我们可以写*“计算机,喝杯茶”*,但实际上我们不得不屈服于编程语言的规则......;) – deceze

回答

3

我如何以不改变接口这项工作?

你不能,接口本质上是有缺陷的。这真的是你的问题的答案。


在继续,虽然,以“我能做些什么,而不是”:

如果你需要有一个初始化过程中调用回调函数,你需要将它传递给构造函数,而不是单独为onInit方法。

class Foo { 
    constructor(callback) { 
    this.onInit =() => { 
     callback(); // Call the callback 
     return this; // Chaining seemed important in your code, so... 
    }; 
    // Note: Constructors don't return anything 
    } 
} 

new Foo(() => console.log('baz')); 

在你所说的评论:

我明白你的意思,但事实是,我的图书馆是new Something().onCreate().onUpdate()

这听起来像你可能想采用builder pattern代替:

class Foo { 
    constructor(callbacks) { 
     // ...use the callbacks here... 
    } 
    // ... 
} 
Foo.Builder = class { 
    constructor() { 
     this.callbacks = {}; 
    } 
    onCreate(callback) { 
     this.callbacks.onCreate = callback; 
    } 
    onUpdate(callback) { 
     this.callbacks.onUpdate = callback; 
    } 
    // ... 
    build() { 
     // Validity checks here, do we have all necessary callbacks? 
     // Then: 
     return new Foo(this.callbacks); 
    } 
}; 

let f = new Foo.Builder().onCreate(() => { /*...*/}).onUpdate(() => { /*... */}).build(); 

...虽然是公平的,建造者模式的一个很大的优势(虽然不是全部)可以通过JavaScript的只是传递对象为constructor直接做您的验证那里,如实现:

let f = new Foo({ 
    onCreate:() => { /*...*/}, 
    onUpdate:() => { /*...*/} 
}); 
+0

谢谢,我将在构造函数选项中移动所有内容,与语言作斗争是没用的:/ –

1

假设onInit应该是某种类型的钩子,每当一个对象被实例化时都会被同步调用,你不能在实例级别上解决这个问题。

您可以onInit静态函数,就像这样:

class Foo { 
 
    constructor() { 
 
    // whatever 
 
    Foo.onInit(); 
 
    } 
 

 
    static onInit() {} // empty default 
 
} 
 

 
Foo.onInit =() => console.log('baz'); // Override default with your own function 
 
const f = new Foo(); 
 
const f2 = new Foo();

+0

谢谢,但这样做,我需要将命令分成多行,难道你没有想法把它作为一个链接命令列表?我猜可能是黑客.. –

+0

当你有命令的基础时,已经太晚了,所以没有。恐怕不可能。 –