设计模式有很多,不定时更新
这只是在下的一点浅见,若有不妥,请多指教
目录:
1.沙箱模式(模块模式/Module模式)
1.2 立即执行函数表达式(IIFE)
2.监听者模式
3.严格模式
1.沙箱模式(模块模式/Module模式)
什么是沙箱模式?
做iOS开发的都知道,每一个app都有一个沙盒,保存的是这个app的数据,外界其他的app是访问不到的,这样就很安全,隐私.
沙箱模式就是为了达到类似这样的目的产生的
----沙箱模式不会在外界暴露任何的全局变量,也就减少了全局变量重名的情况,不会造成全局变量污染
----沙箱中的所有数据,都是和外界完全隔离的,外界无法对其进行修改,达到安全的目的
如何实现沙箱模式?
利用函数可以构建作用域,其上级作用域不能直接访问下级作用域中的数据的特点
具体是用立即执行函数表达式(IIFE: Immediately Invoked Function Expression)
先看一个简单的例子:
<script>
//普通模式1
var num1 = 0;
for(var i = 1;i <= 100; i++)
{
num1 += i;
}
console.log(num1);//5050
//普通模式2
function test() {
var num2 = 0;
for(var i = 1;i <= 100; i++)
{
num2 += i;
}
console.log(num2);//5050
}
test();
//沙箱模式
(function () {
var num3 = 0;
for(var i = 1;i <= 100; i++)
{
num3 += i;
}
console.log(num3);//5050
})();
console.log(num1);//还可以打印5050
console.log(num2);//爆红,num2 is not defined
console.log(num3);//爆红,num3 is not defined
</script>
----从这个例子可以看出沙箱模式的简单写法就是用一个IIFE把代码包起来即可
----相比于第一种写法,沙箱模式写法省了两个全局变量名( num1 与 i )和一个全局函数名( test )
----相比于第二种写法,功能是相同的,但省了一个全局函数名( test )
沙箱模式一般用在哪里?
1.我们自己可以书写功能独立的一些组件
(例如自己封装的js函数,在一个.js文件中,按照沙箱模式用一个立即执行函数包起来即可)
2.还可以应用在书写第三方框架,或者为第三方框架书写插件
(例如把jQuery对象代替window传进去就可以)
可以保证自己内部的成员变量不被外界修改
jQuery中的沙箱模式
1 2jQuery中的沙箱模式是这样实现的:
//jQuery中的沙箱模式
(function (w) {
var Cat = {
eat:function () {
console.log("吃");
}
}
w.cat = w.$ = Cat;
})(window)
window.cat.eat();//吃
window.$.eat();//吃
cat.eat();//吃
$.eat();//吃
还有一种写法:
//第二种写法
(function () {
var Cat = {
eat:function () {
console.log("吃");
}
}
window.cat = window.$ = Cat;
})()
window.cat.eat();//吃
window.$.eat();//吃
cat.eat();//吃
$.eat();//吃
这两种写法都是给window增加了一个cat和$的属性,并指向同一个对象Cat
实际上第二种写法与第一种写法没有用法上的区别,只是逻辑上,概念上的区别,
意思是我们没有直接用外界的window全局对象,而是使用自己的形参w,
只不过在调用的时候把window作为实参传了进来,
实现了沙箱模式逻辑上与外界隔绝
在我们使用的时候,
如果我们需要对外界暴露一些属性或者方法,
就可以将这些属性或者方法添加到window全局对象上,
但是这个全局对象不可直接引用,因为引用会破坏沙箱原则,
所以我们用传参的形式把window对象传入沙箱内,
此时沙箱内使用window对象的时候,不会再去全局搜索window对象,
而是使用的沙箱内部定义的形参
1.2 立即执行函数表达式(IIFE: Immediately Invoked Function Expression)
稍微写一点IIFE
立即执行函数表达式也叫自调用匿名函数
特点是没有函数名,在页面加载完成时就执行一次,且内部的变量不会被外界访问到,正好符合沙箱模式
(function(){})();
(function(){}());
是两种JavaScript立即执行函数的常见写法
<script>
(function (w) {
console.log(w);
})("哈哈哈");
(function (w) {
console.log(w);
}("哈哈哈"));
//不用括号()也可以
//比如+ - ! 等等其他奇葩符号,不过没人会这么用吧...
!function (w) {
console.log(w);
}("哈哈哈");
//三者都是打印哈哈哈
</script>
不多写了,可以看看其他人的文章
<a href="http://www.jianshu.com/p/05ab2eacd11b">js中(function(){…})()立即执行函数写法理解</a>
<a href="http://www.jianshu.com/p/5b5de313015c">JavaScript IIFE</a>
2.监听者模式
和OC中的通知一样,类似于广播,通常用来处理一对多的关系
主要实现方式为:
设置一个监听者(对象),维护一个听众队列(对象数组),监听一个事件(函数)
当事件发生时,告知所有的听众,听众各自做出反应,
一个听众可以理解为是一个回调,告知听众即执行回调
先看个基本的实现:
<script>
// 监听者
var jianTingZhe = {
// 听众列表
listeners: [],
// 此事件触发时,告知所有的听众执行方法
sing: function() {
this.listeners.forEach( function( listen ) {
listen();
});
}
}
jianTingZhe.listeners.push( function() {
console.log( '你问~我爱~你有~多深~' );
} );
jianTingZhe.listeners.push( function() {
console.log( '我爱~你有~几分~' );
} );
jianTingZhe.listeners.push( function() {
console.log( '月亮代表我的心' );
} );
// 触发事件,开始唱歌
jianTingZhe.sing();
//打印
//你问~我爱~你有~多深~
//我爱~你有~几分~
//月亮代表我的心
</script>
再看一个与沙箱模式结合的例子:
<script>
// 监听者
var jianTingZhe = {
// 听众列表
listeners: {
listener1: [],
listener2: [],
listener3: []
},
// sing1触发时,告知所有监听sing1的听众
sing1: function() {
this.listeners.listener1.forEach( function( listen ) {
listen();
});
},
// sing2触发时,告知所有监听sing2的听众
sing2: function() {
this.listeners.listener2.forEach( function( listen ) {
listen();
});
},
// sing3触发时,告知所有监听sing3的听众
sing3: function() {
this.listeners.listener3.forEach( function( listen ) {
listen();
});
}
};
// 这是一个模块,整体可以认为是一个听众监听三个事件
(function( w ) {
// sing1听众
jianTingZhe.listeners.listener1.push( function() {
console.log( '你问~我爱~你有~多深~' );
} );
jianTingZhe.listeners.listener1.push( function() {
console.log( '我爱~你有~几分~' );
} );
jianTingZhe.listeners.listener1.push( function() {
console.log( '月亮代表我的心~' );
} );
// sing2听众
jianTingZhe.listeners.listener2.push( function() {
console.log( '今夜还吹着风~想起你好温柔~' );
});
jianTingZhe.listeners.listener2.push( function() {
console.log( '有你的日子分外~的轻松~' );
});
// sing3听众
jianTingZhe.listeners.listener3.push( function() {
console.log( '因为爱情~不会轻易悲伤~' );
});
}( window ));
// 这是另一个模块,整体可以认为是一个听众
(function( w ) {
// sing3听众
jianTingZhe.listeners.listener3.push( function() {
console.log( '所以一切都是幸福的模样~' );
});
}( window ));
jianTingZhe.sing1();
jianTingZhe.sing2();
jianTingZhe.sing3();
//打印
//你问~我爱~你有~多深~
//我爱~你有~几分~
//月亮代表我的心~
//今夜还吹着风~想起你好温柔~
//有你的日子分外~的轻松~
//因为爱情~不会轻易悲伤~
//所以一切都是幸福的模样~
</script>
3.严格模式
我们都知道JS的语法是很松散的,怎么写都对😂,
比如函数后面没有;也可以执行
而严格模式是在ES5出现的,只要启用了严格模式,JS的语法就会变得规范,写得不规范会警告报错等
严格模式可以消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
增加运行速度;
用法:
在.js文件中,若要使用严格模式,则写一行'use strict'
就会告诉解析器下面的代码就必须规范了,要按照ES5以上来解析
例如保留字:
一旦出现Unexpected strict mode reserved word这样的错误说明你用保留字做了参数名了
es6-->implements, interface, let, package, private, protected, public, static, yield
es5-->class, enum, export, extends, import, super
再例如.js中以下代码:
'use strict'
a=123;
运行后会报错a没有被定义,而没有声明严格模式则不会报错
其他设计模式
比如工厂模式在我之前文章里写过了,就不再写了
JS函数的4种调用模式
还有很多不定时更新吧(∩_∩)
网友评论