Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

怎样优雅地编写公共组件 #3

Open
ningmengs opened this issue Sep 3, 2017 · 0 comments
Open

怎样优雅地编写公共组件 #3

ningmengs opened this issue Sep 3, 2017 · 0 comments

Comments

@ningmengs
Copy link
Owner

公共组件的设计模式根据需求大致可以分成两种模式,构造函数模式和模块模式。一般来说,如果需要一个对象的多个不同实例,就使用构造函数模式,否则使用模块模式。

举个栗子:

构造函数模式:
let Fruits = function(){
let config = { //配置项
name:'apple',
cb:null //回调函数
}
function addName(){

}
function getName(){
return name;
}
function init(opt){
Object.assign(config,opt); //对象浅复制
}
init(opt);
//暴露给外界的方法
return {
getName:getName
};};

调用:
let obj1 = new Fruits({
name:'banana',
cb:function(){
alert('');
}
});

模块模式:
let Dialog = (function(){
let config = {
title:'温馨提示',
message:'',
btn:{
sure:{},
cancel:{}
}
}
function alert(){
}
function confirm(){
}
//对外暴露的方法
return {
alert,
confirm
}
}())
调用:
Dialog.alert('参数出错');

两种模式都要遵循的规则:

一.命名空间

命名空间有助于减少程序中所需要的全局变量数量,并且同时还有助于避免命名冲突或

过长的名字前缀。js语言没有内置命名空间,但是我们可以去实现它。可以为应用程序创建一个全局对象,然后将所有功能添加到这个全局对象中,从而在具有大量函数,对象和其他变量的情况下不会污染全局范围。

最佳实践就是创建一个闭包:

let obj = function(){ 其他功能函数写在这里... }
二.声明依赖关系

在模块顶部声明代码所以来的模块是一个非常好的实践。举个例子:

let myFunction = function(){ let event = M.util.Event, dom = M.util.Dom; //使用事件和Dom变量 }
顶部声明依赖关系有许多优点:

1.显示声明依赖向用户表明了他们确定需要的特定脚本文件已经包含在这个页面中。

2.顶部的前期声明开发者很容易发现,并且去解析依赖。

3.解析局部变量的速度要比解析全局变量要快,提升性能。

三.配置参数

每个组件都需要一定的传参,包括函数需要的外界参数,回调函数等,这些参数如果用一个配置项统一管理起来,可以提高可读性性和可维护性。举个例子:

let myFunction = (function(){
let config = {
color:'#fff', //可以先给一个默认值
width:'100px',
height:'100px',
cb:function(){ //默认回调函数
}
}
function init(opt){
Object.assign(config,opt);//这一步是必须的,用于把外部的参数浅复制到内部的配置项,
也就是说如果已经存在某个特定参数,后面传的参数会覆盖它,
如果没有传该参数,那就使用默认值
}
return {
init:init
}
}())
四.私有和特权成员

前面已经说过,要给组件创建一个单独的命名空间,也就是闭包,在闭包范围内的变量和函数都不应该随意的暴露给外界,因为外界的用户可能会随意更改我们的对象。

为了区分私有成员和公共成员,可以return出一个对象,是暴露给外界的接口。在命名上面,私有成员可以加一个前缀 “_”下划线,用以区分。举个例子:

let myFunction = (function(){
let config = {
color:'#fff', //可以先给一个默认值
width:'100px',
height:'100px',
cb:function(){ //默认回调函数
}
}
function _fuc1(){ //私有方法
}
function fuc2(){ //公共方法
}
function init(opt){
Object.assign(config,opt);
}
return {
init:init,
fuc2:fuc2
}
}())
注意:

私有性失效:

有一个特别需要注意的问题是,当直接从一个私有方法返回一个私有变量,并且该变量恰好是一个对象或者数组,那么外面的代码仍然可以访问到这个私有变量,因为它是通过引用传递的。解决的方法很简单,返回的变量可以是对象的一个拷贝,即一个副本。用Object.assign()就可以解决啦。

PS:如有错误欢迎指正!

以上参考:

1.工作时的总结

2.书籍:《javascript模式》

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant