namespace in javascript
js默认是没有namespace的,所以我们在js中定义的任何东西(function, method, object, variable)都是全局性的,甚至在编码中会不断的增加变量等污染全局作用域。幸运的是,我们可以通过Object和IIFE(立即调用的函数表达式)来模拟出我们自己的namespace。这有助于我们更好的管理代码,而不用创建一些无用的全局变量和全局函数。
下面的例子我们分别创建两个同名的方法:
function func1(){
console.log("I am first func")
}
function func1(){
console.log("I am second func")
}
func1(); //打印出 I am second fun1
上面我们模拟在不同的地方定义两个同名的func1, 结果只运行了最新定义的那个,产生了冲突。现在我们通过将两个函数分别放到不同的namespace下处理下命名冲突,使两个方法逻辑隔离开来。
有几种方法可供选择:
第一种: 使用Object模型来模拟
我们把变量和函数包在一个充当namespace的Object里面,然后通过点号访问被包裹的变量和函数.
var MyNamespace1 = MyNamespace1 || {};
var MyNamespace2 = MyNamespace2 || {};
MyNamespace1.func1 = function(){
console.log("I am first func")
}
MyNamespace2.func1 = function(){
console.log("I am second func")
}
MyNamespace1.func1(); // I am first fun1
MyNamespace2.func1(); // I am second fun1
第二种:使用IIFE(Immediately invoked function expression) 立即调用的函数表达式
IIFE是包含在一对括号内的匿名函数,它能够立即执行,这对括号为它们内部的所有代码创建了一个局部的scope,并使该匿名函数成为函数表达式。适用于定义一些不会在其它地方调用的函数
最外面的一对括号将其中的所有内容都转换为表达式,因为括号不能包含JavaScript语句。函数定义后的另一对括号立即调用该函数。我们来看一个例子。
(function(){
function func1(){
console.log("I am first func1")
}func1();
}());
(function() {
function func1(){
console.log("I am second fun1");
} func1();
}());
(function(){
var x = 123;
console.log(x);
})(); // 直接打印出123,且只打印一次
第三种:使用block,let或const声明
在es5中我们可以使用上面的IIFE模式。如果需要严格的限制变量的范围,在es6中可以使用block中let(或const)声明
{
let temp = function fun1(){
console.log("I am first fun1");
}
temp(); // "I am first fun1"
} // 实时调用
fun1(); //报错,let声明的函数作用域为block内部,在block外部无法调用到
{
let temp= function fun1(){
console.log("I am second fun1");
}
temp(); //"I am second fun1"
} // 实时调用
fun1(); //报错,let声明的函数作用域为block内部,在block外部无法调用到
Ref:
https://dev.to/muhammadridwan/namespace-in-js-5dbj
https://github.com/stevekwan/best-practices/blob/master/javascript/best-practices.md