1、模块形式
在马上实行函数表达式中定义的变量和要领,在该函数外部是接见不到的,只能经由过程该函数供应的接口,”有限定的”举行接见;经由过程函数的作用域,处理了属性和要领的封装题目。
最常见的马上实行函数写法有以下两种:
(function(){ /* code */ }())
或许
(function(){ /* code */ })()
模块形式代码:
let Person = (function(){
var age = "12";
var name = "jerry";
function getAge(){
return age;
}
function getName(){
return name;
}
return {
getAge: getAge,
getName: getName
}
})()
console.log(age, 'age'); // 报错: Uncaught ReferenceError: age is not defined
console.log(name, 'name'); // 空字符串,为啥不报错?看底部备注
console.log(Person.age); // undefined
console.log(Person.name); // undefined
// 只能经由过程Person供应的接口接见响应的变量
console.log(Person.getName()); // jerry
console.log(Person.getAge()); // 12
2、组织函数形式
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.printName = function(){
console.log(this.name)
}
Person.prototype.printAge = function(){
console.log(this.age)
}
function Student(name,age){
// 继续 Person 的属性
Person.call(this,name,age)
}
function create(prototype){
function F(){}
F.prototype = prototype
return new F()
}
// 让Student的原型指向一个对象,该对象的原型指向了Person.prototype,经由过程这类体式格局继续 Person 的要领
Student.prototype = create(Person.prototype)
Student.prototype.printAge = function(){
console.log(this.age)
}
let student = new Student('jerry',12)
student.printName() // "jerry"
student.printAge() // "12"
3、夹杂形式
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.printName = function(){
console.log(this.name)
}
function Student(name,age){
// 继续 Person 的属性
Person.call(this, name, age)
}
function create(prototype){
function F(){}
F.prototype = prototype
return new F()
}
// 让Student的原型指向一个对象,该对象的原型指向了Person.prototype,经由过程这类体式格局继续 Person 的要领
Student.prototype = create(Person.prototype)
Student.prototype.printAge = function(){
console.log(this.age)
}
let student = new Student('jerry', 12)
student.printName() // "jerry"
student.printAge() // 12
4、工场形式
function Person(name, age){
let person = new Object()
person.name = name
person.age = age
person.printName = function(){
console.log(this.name)
}
person.printAge = function(){
console.log(this.age)
}
return person
}
let person = Person('jerry',12)
person.printName()
person.printAge()
5、单例形式
let Singleton = (function(){
let instantiated
function init(){
/*定义单例代码*/
return{
publicMethod: function(){
console.log("Hello World");
},
publicProperty: "Test"
}
}
return{
getInstance: function(){
if(!instantiated){
instantiated = init()
}
return instantiated
}
}
}())
Singleton.getInstance().publicMethod()
单例之间的通信:
竖立两个自力的对象:jim&&lily,两者之间经由过程door直接通信,假如没有新建door,有直接通信。代码以下:
let jim = (function(argument){
let door
let jimHome = function(msg){
this.doorbell = msg
}
let info = {
sendMessage: function(msg){
if(!door){
door = new jimHome(msg)
}
return door
},
coming: function(){
return "来了来了"
}
}
return info
}())
let lily = {
callJim: function(msg){
let _xw = jim.sendMessage(msg)
alert(_xw.doorbell)
console.log(_xw.doorbell)
_xw = null // 守候渣滓接纳
let coming = jim.coming()
console.log(coming)
}
}
lily.callJim("叮咙")
6、宣布-定阅形式
定阅宣布形式定义了一种一对多的依靠关联,让多个定阅者对象同时监听某一个主题对象。这个主题对象在本身主题变化时,会关照一切定阅者对象,使他们可以自动更新本身的状况。
将一个体系分割成一系列相互协作的类有一个很不好的副作用:须要保护响应对象间的一致性,如许会给保护、扩大和重用都带来不方便。当一个对象的转变须要同时转变其他对象,而且他不知道详细有若干对象须要转变时,此时发起运用定阅宣布形式。
运用场景:
DOM事宜。DOM事宜是一种典范的宣布-定阅形式,对一个DOM节点的DOM事宜举行监听;当操纵DOM节点时,触发响应的事宜并实行函数。
自定义时候。指定宣布者,类似于一个对象(key:value);key示意事宜的称号,value是一个数组;宣布音讯后,遍历value的数组,顺次实行定阅者的回调函数。
运用Demo以下:
let Event = (function(){
var events = {}
function on(evt, handler){
events[evt] = events[evt]||[];
events[evt].push({
handler:handler
})
}
function fire(evt,args){
if(!events[evt]){
return
}
for(var i=0;i<events[evt].length;i++){
events[evt][i].handler(args)
}
}
function off(evt){
delete events[evt]
}
return {
on: on,
fire: fire,
off: off
}
}())
Event.on('change', function(val){
console.log('change事宜,value is' + val)
})
Event.on('click', function(val){
console.log('click事宜,value is '+ val)
})
Event.fire('change', 'jerry1')
Event.fire('click', 'jerry2')
Event.off('change')
备注:console.log(name, ‘name’)没有报错,是因为name是浏览器的窗口变量名,已存在于浏览器内部。