2017-08-07 5 views
1

私はオブジェクトリテラルがありますJavaScript Object Literalの__proto__プロパティに関数を追加することをお勧めしますか?

var tasks = {}; 

私は基本的にとても好きに物事を追加します。

function addTask(task) { 
    tasks[task.id] = task 
} 

は私が各タスクにstart関数を呼び出すことができるようにそれを修正したいの。だから、:

var tasks = {}; 
tasks.__proto__.start = function(key) { 
    // do stuff with this[key] 
} 

function addTask(task) { 
    tasks[task.id] = task 
    tasks.start(task.id) 
} 

私はそれがプロトオブジェクトを回避し、それが実行速度が遅くなりことをするのが最善だと聞きました。しかし私はそれを再割り当てしていない、私はそれに追加しています。

もっと良いと思われる方法がありますか?

+0

コンストラクタ/ファクトリ関数が必要です。 – undefined

答えて

4

これにはプロトタイプを使用する必要はありません。より高いレベルで抽象化された共通の機能が必要な多くのインスタンスを作成しているわけではなく、tasksオブジェクトにメソッドを追加するだけで済みます。

const tasks = { 
    start(key) { 
    const task = this[key] 
    // do stuff with task 
    } 
} 

// example call 
tasks.start('123'); 

既存のキーとは衝突がありませんを確認する場合は、代わりにSymbolを使用することができます。

​​

また、単に同様に、あなたのaddTask関数に、これを行い、スタンドアロンの機能を持つことができます:あなたが間の衝突を心配する必要はありませんので、このスタンドアロン機能を持つ

function start(tasks, key) { 
    const task = tasks[key] 
    // do stuff with task 
} 

// example call 
start(tasks, '123') 

は、おそらく優れていますタスクキーとメソッド名。

また、この分離を行いラッパーオブジェクトを作成することができます。

const taskManager = { 

    tasks: {} // map of key to task 

    // methods 
    add(task) { 
    this.tasks[task.id] = task; 
    this.start(task.id); 
    } 
    start(key) { 
    const task = this.tasks[key]; 
    // do stuff with task 
    } 
} 

// example usage 
taskManager.start('123') 
このアプローチの利点は、あなたの tasksがいる tasksがあるべき範囲を絞る、それらに操作した容器内に封入されていることである

どのような関数がタスク上で使用されることが意図されているかを明確にする(プログラマーに示唆する)。

あなたが複数のタスクマネージャを持つことを計画している場合、使用した試作品は、ここでは意味をなさないかもしれません:

class TaskManager { 
    constructor() { 
    this.tasks = {} // map of key to task 
    } 

    // methods 
    add(task) { 
    this.tasks[task.id] = task; 
    this.start(task.id); 
    } 
    start(key) { 
    const task = this.tasks[key]; 
    // do stuff with task 
    } 
} 

// example usage 
new TaskManager().start('123') 
+0

ありがとうございます。タスクマネージャのエンティティを参照すると便利であり、それを見たことがありません –

+0

意味的には「var」としてタスクマネージャを宣言する方が良いでしょうか?タスクマネージャは時間の経過と共に変化するからです。 –

+0

'const'は値にではなく参照に適用されます。 'const'で宣言された変数を別のものに向けることはできませんが、値自体を変更することはできます。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const – nem035

3

これは、両方のパフォーマンスとブラウザの互換性の観点から、良いアイデアではありません。

mozilla's documentationからこれらの警告を参照してください。

警告:[[プロトタイプ]]は、オブジェクトの非常に遅い 操作、JavaScriptエンジンは、プロパティがアクセスを最適化する方法現代 の性質によって、ある変更、中すべてのブラウザとJavaScriptエンジン の継承を変更するパフォーマンスへの影響は微妙で遠くにあり、 はobjで費やされた時間に限定されません。 proto = ... [[プロトタイプ]]が変更されたオブジェクトにアクセスできるコードに拡張することができます。あなたがパフォーマンスを気にしているなら、 はオブジェクトの[[Prototype]]の設定を避けるべきです。代わりに、Object.create()を使用して希望の[[Prototype]]で 新しいオブジェクトを作成します。

-

警告:のObject.prototypeながら。 protoは今日ほとんどの ブラウザでサポートされていますが、その存在と正確な動作は、ウェブブラウザの互換性を保証するために従来の機能としてECMAScript 2015仕様の のみが標準化されています。より良いサポートのために、代わりにObject.getPrototypeOf()のみが使用されるように をお勧めします。

関連する問題