JavaScript-オブジェクトリテラルの利点
-
05-07-2019 - |
質問
関数の束を単に書くのではなく、オブジェクトリテラルを使用する必要があることを読みました。
私はこれまで理解していないので、誰かがオブジェクトリテラルの利点を例で説明できますか。
ありがとう
解決
Russ Camが言ったように、グローバルな名前空間を汚染することは避けます。これは、複数の場所(TinyMCEなど)からのスクリプトを組み合わせる最近では非常に重要です。
Alex Sextonが言ったように、それは良いコード編成にもなります。
この手法を使用している場合、モジュールパターンを使用することをお勧めします。これはまだオブジェクトリテラルを使用しますが、スコープ関数からの戻り値として:
var MyThingy = (function() {
function doSomethingCool() {
...
}
function internalSomething() {
....
}
function anotherNiftyThing() {
// Note that within the scoping function, functions can
// call each other direct.
doSomethingCool();
internalSomething();
}
return {
doSomethingCool: doSomethingCool,
anotherNiftyThing: anotherNiftyThing
};
})();
外部使用:
MyThingy.doSomethingCool();
スコープ関数はすべての関数にラップされ、すぐに呼び出して戻り値を保存します。利点:
- 関数は通常宣言されているため、名前を持っています。 (
{name:function(){...}}
形式の場合、関数を参照するプロパティには名前がありますが、関数はすべて匿名です。)デバッガーでスタックを呼び出して、どの関数が例外をスローしたかを通知します。 (2015年の更新:最新のJavaScript仕様、ECMAScript第6版では、JavaScriptエンジンが関数の名前を推測する多くの方法が定義されています。その1つは、関数が{name:function(){...}}
の例。エンジンがES6を実装すると、この理由はなくなります。) - モジュールでのみ使用されるプライベート関数(上記の
internalSomething
など)を自由に使用できます。ページ上の他のコードはこれらの関数を呼び出すことができません。彼らは本当にプライベートです。 returnステートメントで最後にエクスポートするもののみが、スコープ関数の外側に表示されます。 - 実装が完全に変更された場合(IE-vs-W3Cのもの、SVG対Canvasなど)、環境に応じて異なる関数を簡単に返すことができます。
さまざまな関数を返す例:
var MyUtils = (function() {
function hookViaAttach(element, eventName, handler) {
element.attachEvent('on' + eventName, handler);
}
function hookViaListener(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
}
return {
hook: window.attachEvent ? hookViaAttach : hookViaListener
};
})();
MyUtils.hook(document.getElementById('foo'), 'click', /* handler goes here */);
他のヒント
オブジェクトリテラル(別名:オブジェクトリテラルパターン)を使用しても、グローバルに宣言された多くの関数を使用するほどグローバルな名前空間を汚染することはなく、論理的な方法でコードを整理するのにも役立ちます
たとえば、このオブジェクトリテラル
var obj = {
find : function(elem) { /* find code */ },
doSomething: function() { /* doSomething code */ },
doSomethingElse: function() { /* doSomethingElse code */ }
}
比較
function find(elem) { /* find code */ },
function doSomething() { /* doSomething code */ },
function doSomethingElse() { /* doSomethingElse code */ }
は3つと比較して、グローバルオブジェクトに1つのプロパティのみを作成します。そうすると、次のような関数を簡単に使用できます
obj.doSomething();
Rebecca Murpheyは、今年のjQuery ConferenceでObject Literalsについて講演しました。それらを使用する最良の理由の1つは、単に優れたコード編成です。
オブジェクトリテラルパターンに関するRebeccaの記事は次のとおりです。 http://rmurphey.com/blog/2009/10/15/using-objects-to-organize-your-code/
オブジェクトリテラルはコードを整理するための明確な方法であるため、常にオブジェクトリテラルを使用しています。それがプロトタイプが好きではない理由です。それは面倒です。
関数は、上記の誰かがオブジェクトリテラル以上に名前空間を汚染することはありません。
次のようなリテラルを簡単に書くことができます
var obj = {}
var find = function(elem) { /* find code */ },
var doSomething = function() { /* doSomething code */ },
var doSomethingElse = function() { /* doSomethingElse code */ }
これは、関数と同じように多くのグローバルオブジェクトを作成することで汚染されます。同様にできること:
(function() {
function find(elem) { /* find code */ },
function doSomething() { /* doSomething code */ },
function doSomethingElse() { /* doSomethingElse code */ }
})();
これらのグローバルオブジェクトは作成されません(すべてがJSのオブジェクトです)
この方法では、まだグローバルオブジェクトのロードを作成しません。
私の考えでは、オブジェクトリテラルには2つの利点があります。 1つはjQueryなどの多くのプラグインで使用されるため、人々はより身近で読みやすいです。データをプラグインに簡単に渡すことができます。パブリックメソッドとプライベートメソッドの両方を簡単に作成できます。...
オブジェクトのインスタンスを作成するたびにすべてのメソッドが複製されるため、速度は遅くなります。メソッドのコピーが1つあり、新しいオブジェクトは単にプロトタイプを参照するだけなので、プロトタイプの場合はそうではないことを理解しています。
もちろん間違っているかもしれません...