オブジェクトと関数が他の同じ名前のオブジェクトと関数によって上書きされないように、JavaScriptで名前空間を作成するにはどうすればよいですか?私は以下を使用しました:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
これを行うよりエレガントまたは簡潔な方法はありますか?
オブジェクトと関数が他の同じ名前のオブジェクトと関数によって上書きされないように、JavaScriptで名前空間を作成するにはどうすればよいですか?私は以下を使用しました:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
これを行うよりエレガントまたは簡潔な方法はありますか?
回答:
私はこれが好き:
var yourNamespace = {
foo: function() {
},
bar: function() {
}
};
...
yourNamespace.foo();
MyApp
、例えばMyApp.Views.Profile = {}
いうよりMyApp.users = {}
とMyViews.Profile = {}
。必ずしも2つのレベルの深さがある必要はありません。
私はEnterprise jQueryサイトにあるアプローチを使用します:
以下は、プライベートおよびパブリックプロパティと関数を宣言する方法を示す例です。すべては、自己実行型の無名関数として行われます。
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "\t\n Butter \n\t" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
したがって、パブリックメンバーの1つにアクセスする場合は、単にアクセスするskillet.fry()
か、skillet.ingredients
ます。
本当にすばらしいのは、まったく同じ構文を使用して名前空間を拡張できることです。
//Adding new Functionality to the skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
undefined
引数3番目の
undefined
引数は、valueの変数のソースですundefined
。今日でもまだ関連性があるかどうかはわかりませんが、古いブラウザー/ JavaScript標準(ecmascript 5、javascript <1.8.5〜firefox 4)を使用している場合、グローバルスコープ変数undefined
は書き込み可能であるため、誰でもその値を書き換えることができます。3番目の引数(値が渡されない場合)はundefined
、名前空間/関数をスコープとするという名前の変数を作成します。名前空間の作成時に値が渡されなかったため、デフォルトで値が使用されますundefined
。
undefined
引数はvalueの変数のソースですundefined
。古いブラウザ/ JavaScript標準(ecmascript 5、javascript <1.8.5〜firefox 4)で作業している間、グローバルスコープ変数undefined
は書き込み可能であるため、誰でもその値を書き換えることができます。渡していない3番目の引数を追加すると、値がvalue undefined
になるためundefined
、外部ソースによって書き換えられない名前空間スコープを作成していました。
window.skillet = window.skillet || {}
は、複数のスクリプトが実行する順序が事前にわからない場合に、同じ名前空間に安全に追加できることです。これは、コードを壊すことなくスクリプトの包含を任意に並べ替えることができるようにする場合、またはasync属性を使用してスクリプトを非同期にロードする場合に、実行順序が保証されない場合に役立ちます。stackoverflow.com/questions/6439579/…を
それを行う別の方法は、オブジェクトリテラルフォームよりも制限が少ないと私は考えていますが、これは次のとおりです。
var ns = new function() {
var internalFunction = function() {
};
this.publicFunction = function() {
};
};
上記のほとんどのようであるモジュールパターンとあなたのこと好きかどうか、オブジェクトリテラルの剛性構造を回避しながら、それは、あなたがパブリックとして、すべての機能を公開することができます。
ns().publicFunction()
、つまり... ns.publicFunction()
機能します。
new
キーワードの前にfunction
キーワードがあるためです。基本的に何をしているのかというと、それは無名関数を宣言し(そして関数として、それもコンストラクターです)、それからを使用してコンストラクターとしてすぐにそれを呼び出しますnew
。そのため、内部に格納される最後の値ns
は、その匿名コンストラクターの(一意の)インスタンスです。それが理にかなっていると思います。
これを行うよりエレガントまたは簡潔な方法はありますか?
はい。例えば:
var your_namespace = your_namespace || {};
その後、あなたは持つことができます
var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg)
{
alert(arg);
};
with(your_namespace)
{
Bar(Foo.toAlert);
}
var your_namespace = your_namespace = your_namespace || {}
私は通常それをクロージャーに構築します:
var MYNS = MYNS || {};
MYNS.subns = (function() {
function privateMethod() {
// Do private stuff, or build internal.
return "Message";
}
return {
someProperty: 'prop value',
publicMethod: function() {
return privateMethod() + " stuff";
}
};
})();
これを書いてから何年にもわたって私のスタイルは微妙な変化を遂げており、今では次のようにクロージャーを書いています。
var MYNS = MYNS || {};
MYNS.subns = (function() {
var internalState = "Message";
var privateMethod = function() {
// Do private stuff, or build internal.
return internalState;
};
var publicMethod = function() {
return privateMethod() + " stuff";
};
return {
someProperty: 'prop value',
publicMethod: publicMethod
};
})();
このようにして、パブリックAPIと実装が理解しやすくなります。returnステートメントは、実装へのパブリックインターフェイスであると考えてください。
MYNS.subns = MYNS.subns || {}
?
var foo = function
とfunction foo
は似ていますが、プライベートです。JavaScriptは動的に型付けされる性質のため、後者はほとんどのインタープリターのパイプラインでいくつかの命令をスキップするため、わずかに高速です。を使用するvar foo
と、型システムは、そのvarに割り当てられている型を見つけるために呼び出される必要がありますが、を使用するfunction foo
と、型システムはそれが関数であることを自動的に認識するため、2つの関数呼び出しがスキップされ、CPU命令の呼び出しが少なくなります。jmp
、pushq
、popq
、など、短いCPUのパイプラインに変換しています。
function foo
構文がより読みやすいと主張していますが。そして、私はまだ私のバージョンが好きです。
JavaScriptの異なるファイルを作成し、後でそれらをアプリケーションで組み合わせるか、または組み合わせない可能性があるため、それぞれが他のファイルの作業を損なうことなく名前空間オブジェクトを回復または構築できる必要があります...
1つのファイルで名前空間を使用する可能性がありますnamespace.namespace1
。
namespace = window.namespace || {};
namespace.namespace1 = namespace.namespace1 || {};
namespace.namespace1.doSomeThing = function(){}
別のファイルが名前空間を使用したい場合がありますnamespace.namespace2
:
namespace = window.namespace || {};
namespace.namespace2 = namespace.namespace2 || {};
namespace.namespace2.doSomeThing = function(){}
これらの2つのファイルは、衝突することなく、一緒にまたは離れて存在できます。
これは、Stoyan StefanovがJavaScriptパターンの本でどのように実行したかを示したものです(自動生成されたAPIドキュメントを可能にするコメントや、カスタムオブジェクトのプロトタイプにメソッドを追加する方法も示しています)。
/**
* My JavaScript application
*
* @module myapp
*/
/** @namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};
/**
* A maths utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {
/**
* Sums two numbers
*
* @method sum
* @param {Number} a First number
* @param {Number} b Second number
* @return {Number} Sum of the inputs
*/
sum: function (a, b) {
return a + b;
},
/**
* Multiplies two numbers
*
* @method multi
* @param {Number} a First number
* @param {Number} b Second number
* @return {Number} The inputs multiplied
*/
multi: function (a, b) {
return a * b;
}
};
/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} First name
* @param {String} Last name
*/
MYAPP.Person = function (first, last) {
/**
* First name of the Person
* @property first_name
* @type String
*/
this.first_name = first;
/**
* Last name of the Person
* @property last_name
* @type String
*/
this.last_name = last;
};
/**
* Return Person's full name
*
* @method getName
* @return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
return this.first_name + ' ' + this.last_name;
};
私はこのアプローチを使用します:
var myNamespace = {}
myNamespace._construct = function()
{
var staticVariable = "This is available to all functions created here"
function MyClass()
{
// Depending on the class, we may build all the classes here
this.publicMethod = function()
{
//Do stuff
}
}
// Alternatively, we may use a prototype.
MyClass.prototype.altPublicMethod = function()
{
//Do stuff
}
function privateStuff()
{
}
function publicStuff()
{
// Code that may call other public and private functions
}
// List of things to place publically
this.publicStuff = publicStuff
this.MyClass = MyClass
}
myNamespace._construct()
// The following may or may not be in another file
myNamespace.subName = {}
myNamespace.subName._construct = function()
{
// Build namespace
}
myNamespace.subName._construct()
外部コードは次のようになります。
var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);
ns = ns || {}
それが他の予期しない結果につながることができ、より守備のように見えるかもしれません。
これは、namespace.jsへのuser106826のリンクのフォローアップです。プロジェクトはGitHubに移動したようです。現在はsmith / namespacedotjsです。
私は小さなプロジェクトでこの単純なJavaScriptヘルパーを使用してきましたが、これまでのところ、名前空間の処理とモジュール/クラスのロードを処理するのに十分なほど軽量で多用途なようです。グローバルな名前空間だけでなく、自分が選択した名前空間にパッケージをインポートできるようになれば素晴らしいです...ため息をつくだけでなく、それも重要です。
名前空間を宣言してから、その名前空間でオブジェクト/モジュールを定義できます。
Namespace('my.awesome.package');
my.awesome.package.WildClass = {};
別のオプションは、名前空間とその内容を一度に宣言することです:
Namespace('my.awesome.package', {
SuperDuperClass: {
saveTheDay: function() {
alert('You are welcome.');
}
}
});
その他の使用例については、ソースの example.jsファイルをご覧ください。
サンプル:
var namespace = {};
namespace.module1 = (function(){
var self = {};
self.initialized = false;
self.init = function(){
setTimeout(self.onTimeout, 1000)
};
self.onTimeout = function(){
alert('onTimeout')
self.initialized = true;
};
self.init(); /* If it needs to auto-initialize, */
/* You can also call 'namespace.module1.init();' from outside the module. */
return self;
})()
プライベートにしたい場合local
はsame
、必要に応じて変数を宣言し、好きself
に割り当てlocal.onTimeout
ます。
名前空間を提供する単純な関数を宣言できます。
function namespace(namespace) {
var object = this, tokens = namespace.split("."), token;
while (tokens.length > 0) {
token = tokens.shift();
if (typeof object[token] === "undefined") {
object[token] = {};
}
object = object[token];
}
return object;
}
// Usage example
namespace("foo.bar").baz = "I'm a value!";
プライベートスコープが必要な場合:
var yourNamespace = (function() {
//Private property
var publicScope = {};
//Private property
var privateProperty = "aaa";
//Public property
publicScope.publicProperty = "bbb";
//Public method
publicScope.publicMethod = function() {
this.privateMethod();
};
//Private method
function privateMethod() {
console.log(this.privateProperty);
}
//Return only the public parts
return publicScope;
}());
yourNamespace.publicMethod();
それ以外で、プライベートスコープを使用しない場合:
var yourNamespace = {};
yourNamespace.publicMethod = function() {
// Do something...
};
yourNamespace.publicMethod2 = function() {
// Do something...
};
yourNamespace.publicMethod();
Moduleパターンはもともと、従来のソフトウェアエンジニアリングのクラスにプライベートとパブリックの両方のカプセル化を提供する方法として定義されていました。
Moduleパターンを使用する場合、それを使い始めるために使用する単純なテンプレートを定義すると便利な場合があります。名前空間、パブリック変数、プライベート変数について説明します。
JavaScriptでは、モジュールパターンを使用してクラスのコンセプトをさらにエミュレートし、単一のオブジェクト内にパブリック/プライベートメソッドと変数の両方を含めることができるようにして、グローバルスコープから特定の部分を保護します。その結果、ページ上の追加のスクリプトで定義されている他の関数と関数名が競合する可能性が減少します。
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
メリット
なぜモジュールパターンが良い選択なのですか?手始めに、少なくともJavaScriptの観点から見ると、オブジェクト指向のバックグラウンドを使用している開発者にとっては、真のカプセル化のアイデアよりもずっとクリーンです。
次に、プライベートデータをサポートします。したがって、モジュールパターンでは、コードのパブリック部分はプライベート部分にアクセスできますが、外部の世界はクラスのプライベート部分に触れることができません。
短所
モジュールパターンの欠点は、パブリックメンバーとプライベートメンバーの両方に異なる方法でアクセスするため、可視性を変更したい場合、メンバーが使用された各場所を実際に変更する必要があることです。
また、後でオブジェクトに追加されるメソッドのプライベートメンバーにアクセスすることもできません。とはいえ、多くの場合、モジュールパターンは依然として非常に有用であり、正しく使用すると、アプリケーションの構造を改善できる可能性があります。
明らかにするモジュールパターン
モジュールパターンに少し慣れたところで、少し改善されたバージョン、Christian HeilmannのRevealing Moduleパターンを見てみましょう。
公開モジュールパターンは、あるパブリックメソッドを別のメソッドから呼び出したり、パブリック変数にアクセスしたりするときにメインオブジェクトの名前を繰り返す必要があったという事実にハイルマンが苛立っていたために発生しました。彼が公表したかったものの文字表記に反対すること。
彼の努力の結果は、更新されたパターンであり、プライベートスコープですべての関数と変数を定義し、パブリックとして公開したいプライベート機能へのポインターを持つ匿名オブジェクトを返すだけでした。
表示モジュールパターンの使用例は以下にあります
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
メリット
このパターンにより、スクリプトの構文をより一貫させることができます。また、モジュールの最後で、どの関数と変数にパブリックにアクセスできるかが明確になり、読みやすくなります。
短所
このパターンの欠点は、プライベート関数がパブリック関数を参照する場合、パッチが必要な場合にそのパブリック関数をオーバーライドできないことです。これは、プライベート関数が引き続きプライベート実装を参照し、パターンがパブリックメンバーには適用されず、関数にのみ適用されるためです。
プライベート変数を参照するパブリックオブジェクトメンバーも、上記のパッチなしのルールに関する注意事項に従います。
名前空間を作成しましたErlangのモジュールに触発さ。これは非常に機能的なアプローチですが、私が最近JavaScriptコードを作成する方法です。
クロージャにグローバルな名前空間を与え、そのクロージャ内で定義されたセット関数を公開します。
(function(){
namespace("images", previous, next);
// ^^ This creates or finds a root object, images, and binds the two functions to it.
// It works even though those functions are not yet defined.
function previous(){ ... }
function next(){ ... }
function find(){ ... } // A private function
})();
いくつかのライブラリをさまざまなプロジェクトに移植し、トップレベル(静的に名前が付けられた)名前空間を常に変更する必要があるため、名前空間を定義するためにこの小さな(オープンソース)ヘルパー関数を使用するように切り替えました。
global_namespace.Define('startpad.base', function(ns) {
var Other = ns.Import('startpad.other');
....
});
利点の説明は私のブログ投稿にあります。ここでソースコードを入手できます。
私が本当に好きな利点の1つは、ロード順序に関してモジュール間を分離することです。ロードする前に外部モジュールを参照できます。そして、コードが利用可能になると、取得したオブジェクト参照が入力されます。
名前空間には次の構文を使用します。
var MYNamespace = MYNamespace|| {};
MYNamespace.MyFirstClass = function (val) {
this.value = val;
this.getValue = function(){
return this.value;
};
}
var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());
jsfiddle:http ://jsfiddle.net/rpaul/4dngxwb3/1/
私はパーティーに7年遅れていますが、この8年前にかなりの作業をしました。
JavaScriptグローバルネームスペースを尊重しながら(ネームスペースの汚染を防止)、ネームスペースパス内の既存のオブジェクトを壊さないようにしながら、複雑なWebアプリケーションを整理して管理しやすいように、複数のネストされたネームスペースを簡単かつ効率的に作成できることが重要です。 。
上記から、これは2008年頃の私の解決策でした:
var namespace = function(name, separator, container){
var ns = name.split(separator || '.'),
o = container || window,
i,
len;
for(i = 0, len = ns.length; i < len; i++){
o = o[ns[i]] = o[ns[i]] || {};
}
return o;
};
これは名前空間を作成するのではなく、名前空間を作成するための機能を提供します。
これは縮小されたワンライナーに凝縮することができます:
var namespace=function(c,f,b){var e=c.split(f||"."),g=b||window,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g};
使用例:
namespace("com.example.namespace");
com.example.namespace.test = function(){
alert("In namespaced function.");
};
または、1つのステートメントとして:
namespace("com.example.namespace").test = function(){
alert("In namespaced function.");
};
次に、どちらかが次のように実行されます。
com.example.namespace.test();
レガシーブラウザのサポートが必要ない場合は、更新されたバージョン:
const namespace = function(name, separator, container){
var o = container || window;
name.split(separator || '.').forEach(function(x){
o = o[x] = o[x] || {};
});
return o;
};
さて、私namespace
はグローバルな名前空間自体にさらされることはありません。(ベース言語がこれを提供しないのは残念です!)したがって、私は通常、次のようなクロージャーでこれを自分で使用します。
(function(){
const namespace = function(name, separator, container){
var o = container || window;
name.split(separator || '.').forEach(function(x){
o = o[x] = o[x] || {};
});
return o;
};
const ns = namespace("com.ziesemer.myApp");
// Optional:
ns.namespace = ns;
// Further extend, work with ns from here...
}());
console.log("\"com\":", com);
より大きなアプリケーションでは、これはページのロードの開始時に一度だけ定義する必要があります(クライアントベースのWebアプリの場合)。追加のファイルは、保持されている場合、ネームスペース関数を再利用できます(上記では「オプション」として含まれています)。最悪の場合、この関数が数回再宣言された場合-それは数行のコードであり、縮小された場合は少なくなります。
私は皆さんがそのような単純な問題に多すぎるコードを使用していると思います。そのためのリポジトリを作成する必要はありません。これが単一行関数です。
namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
それを試してみてください :
// --- definition ---
const namespace = namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
// --- Use ----
let myNamespace = namespace("a.b.c");
myNamespace.MyClass = class MyClass {};
// --- see ----
console.log("a : ", a);
私のお気に入りのパターンは最近これになりました:
var namespace = (function() {
// expose to public
return {
a: internalA,
c: internalC
}
// all private
/**
* Full JSDoc
*/
function internalA() {
// ...
}
/**
* Full JSDoc
*/
function internalB() {
// ...
}
/**
* Full JSDoc
*/
function internalC() {
// ...
}
/**
* Full JSDoc
*/
function internalD() {
// ...
}
})();
もちろん、最後にreturnを置くこともできますが、関数宣言だけがそれに続く場合は、名前空間とは何か、どのAPIが公開されているかを確認する方がはるかに簡単です。
このような場合に関数式を使用するパターンでは、コード全体を調べないと、どのメソッドが公開されているかを知ることができません。
namespace.a();
Makefileを使用している場合は、これを行うことができます。
// prelude.hjs
billy = new (
function moduleWrapper () {
const exports = this;
// postlude.hjs
return exports;
})();
// someinternalfile.js
function bob () { console.log('hi'); }
exports.bob = bob;
// clientfile.js
billy.bob();
とにかく、約1000行に達したらMakefileを使用することを好みます。なぜなら、Makefile内の1行を削除することで、コードの大きなスワスを効果的にコメントアウトできるからです。それはものをいじるのを簡単にします。また、この手法では、名前空間はプレリュードに一度だけ表示されるため、簡単に変更でき、ライブラリコード内で名前空間を繰り返す必要はありません。
makefileを使用するときにブラウザでライブ開発するためのシェルスクリプト:
while (true); do make; sleep 1; done
これをmakeタスクの 'go'として追加すると、 'make go'を実行して、コーディング時にビルドを更新し続けることができます。
Ionuț G. Stanの回答のかなりのフォローアップですがvar ClassFirst = this.ClassFirst = function() {...}
、を使用してコードが整理されていることの利点を示しています。これは、同じ名前空間内のクラスの名前空間の整理のためにJavaScriptのクロージャスコープを利用しています。
var Namespace = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 123;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
var Namespace2 = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 666;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
new Namespace.ClassSecond()
new Namespace2.ClassSecond()
出力:
Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666
他の言語でパッケージ/ユニットが行うようにもう少し機能する別の名前空間ライブラリを作成しました。JavaScriptコードのパッケージを作成し、そのパッケージを他のコードから参照することができます。
Package("hello", [], function() {
function greeting() {
alert("Hello World!");
}
// Expose function greeting to other packages
Export("greeting", greeting);
});
Package("example", ["hello"], function(greeting) {
// Greeting is available here
greeting(); // Alerts: "Hello World!"
});
2番目のファイルのみをページに含める必要があります。その依存関係(ファイルhello.jsこの例では)が自動的にロードされ、それらの依存関係からエクスポートされたオブジェクトを使用して、コールバック関数の引数が設定されます。
関連するプロジェクトはPackages JSにあります。
私の習慣は、関数myName()をプロパティストレージとして使用し、次に変数myNameを「メソッド」ホルダーとして使用することです...
これで十分かどうかにかかわらず、私を倒してください!私はいつも私のPHPロジックに依存しており、物事は単純に機能します。:D
function myObj() {
this.prop1 = 1;
this.prop2 = 2;
this.prop3 = 'string';
}
var myObj = (
(myObj instanceof Function !== false)
? Object.create({
$props: new myObj(),
fName1: function() { /* code.. */ },
fName2: function() { /* code ...*/ }
})
: console.log('Object creation failed!')
);
if (this !== that) myObj.fName1(); else myObj.fName2();
また、オブジェクトの作成前に確認するために「逆の方法」で行うこともできます。
function myObj() {
this.prop1 = 1;
this.prop2 = 2;
this.prop3 = 'string';
}
var myObj = (
(typeof(myObj) !== "function" || myObj instanceof Function === false)
? new Boolean()
: Object.create({
$props: new myObj(),
init: function () { return; },
fName1: function() { /* code.. */ },
fName2: function() { /* code ...*/ }
})
);
if (myObj instanceof Boolean) {
Object.freeze(myObj);
console.log('myObj failed!');
debugger;
}
else
myObj.init();
JavaScriptでは、名前空間を使用するための事前定義されたメソッドはありません。JavaScriptでは、名前空間を定義する独自のメソッドを作成する必要があります。Oodlesテクノロジーで従う手順は次のとおりです。
名前空間の登録以下は名前空間を登録する機能です
//Register NameSpaces Function
function registerNS(args){
var nameSpaceParts = args.split(".");
var root = window;
for(var i=0; i < nameSpaceParts.length; i++)
{
if(typeof root[nameSpaceParts[i]] == "undefined")
root[nameSpaceParts[i]] = new Object();
root = root[nameSpaceParts[i]];
}
}
名前空間を登録するには、上記の関数を'.'
(ドット)で区切られた名前空間として引数を指定して呼び出します。たとえば、アプリケーション名をoodlesとします。以下の方法で名前空間を作成できます
registerNS("oodles.HomeUtilities");
registerNS("oodles.GlobalUtilities");
var $OHU = oodles.HomeUtilities;
var $OGU = oodles.GlobalUtilities;
基本的には、バックエンドに以下のようなNameSpaces構造を作成します。
var oodles = {
"HomeUtilities": {},
"GlobalUtilities": {}
};
上記の関数では"oodles.HomeUtilities"
、and という名前空間を登録しています"oodles.GlobalUtilities"
。これらの名前空間を呼び出すには、変数、つまりvar $OHU
とvar を作成します$OGU
。
これらの変数は、名前空間を初期化するためのエイリアスにすぎません。今、HomeUtilities
あなたが属している関数を宣言するときはいつでも、次のようにそれを宣言します:
$OHU.initialization = function(){
//Your Code Here
};
上記は関数名の初期化であり、名前空間に配置されます$OHU
。そして、スクリプトファイル内の任意の場所でこの関数を呼び出します。次のコードを使用してください。
$OHU.initialization();
同様に、別の名前空間。
それが役に立てば幸い。
JavaScriptはデフォルトでは名前空間をサポートしていません。したがって、要素(関数、メソッド、オブジェクト、変数)を作成すると、その要素はグローバルになり、グローバルネームスペースを汚染します。名前空間なしで2つの関数を定義する例を見てみましょう。
function func1() {
console.log("This is a first definition");
}
function func1() {
console.log("This is a second definition");
}
func1(); // This is a second definition
常に2番目の関数定義を呼び出します。この場合、名前空間は名前の衝突問題を解決します。