JS设计模式——揭示模块模式

由来

揭示模块模式是对之前模块模式的一种改进。

在模块模式中,公有属性和方法都是写在被返回的字面量对象中,这样,如果想在闭包内部调用公有属性和方法,就需要通过暴露在全局变量中的对象名称去调用。

var nameSpace = (function(){
	return {
		// 公有属性
		firstName: 'Peppa',
		// 公有属性
		lastName: 'Pig',
		getFullName: function() {
			return nameSpace.firstName + ' ' + nameSpace.lastName
		}
	}
})()

nameSpace.getFullName() // => "Peppa Pig"

就像上面实例中展示的,getFullName 方法中需要访问公有属性 firstNamelastName,就必须通过 nameSpace 对象名去调用。

这样的确很别扭,如果想要给 nameSpace 换个对象名,就需要考虑闭包内部的调用。下面我们看看揭示模块模式是怎么优化的。

揭示模块模式

针对上面的模块模式的示例,我们用揭示模块模式做一番优化。

var nameSpace = (function(){
	var firstName = 'Peppa'
	var lastName = 'Pig'
	
	function getFullName() {
		return firstName + ' ' + lastName
	}

	return {
		firstName: firstName,
		lastName: lastName,
		getFullName: getFullName
	}
})()

nameSpace.getFullName() // => "Peppa Pig"

优化后的代码,我们将公有的变量和方法在返回前就做了处理,而返回的对象更加纯粹,增强了可读性。这也是揭示模块模式的优点

同样揭示模块模式也有缺点

var nameSpace = (function() {
	function getFullName() {
		return 'liMing'
	}
	
	// 私有方法
	function sayHello() {
		return 'hi~ ' + getFullName()	
	}

	function firstMeet() {
		console.log(sayHello() + ', I am zkk')
	}

	return {
		getFullName: getFullName,
		firstMeet: firstMeet
	}
})()

nameSpace.firstMeet() // => "hi~ liMing, I am zkk"

上面是一段初次见面打招呼的封装, sayHello 是一个私有方法,但是它调用了 getFullName 这个公有方法,同时 firstMeet 方法调用了 sayHello 私有方法。

现在我需要改变打招呼的对象了,也就是我要修改 getFullName 方法了。

// ... 继续上面代码
nameSpace.getFullName = function() {
	return 'Danny'
}

nameSpace.firstMeet() // => "hi~ liMing, I am zkk"

通过修改我们发现 nameSpace.getFullName 这个方法的确被覆盖了,但是最终的输出并没有改变。

这是因为我们虽然覆盖了返回值中的 getFullName 方法,但是私有方法 sayHello 真正调用的那个 getFullName 还是没有改变。这便是揭示模块模式存在的缺点。

所以到底采用原始的模块模式,还是揭示模块模式,必须依据场景来定。

以上就是揭示模块模式的介绍。

猜你喜欢

转载自blog.csdn.net/userkang/article/details/86690126