本系列出自于《JavaScript设计模式》一书,本书由张容铭所著,以你问我答的方式逐步介绍了JavaScript的各种设计模式,作者写作方式由浅入深,引人入胜,可读性强。
灵活的语言-JavaScript
全局变量
普通函数会在代码执行之前加载到作用域中, 函数名作为全局变量提升到代码最开始执行
1 2 3 4
| function fn(val1, val2) { alert(val1 + val2); } fn(1, 2)
|
函数另一种形式
命名函数, 函数声明会给函数指定一个名字,而函数表达式则是创建一个匿名函数,然后将这个匿名函数赋给一个变量. 函数声明不会提前
1 2 3 4
| var fn = function(val1, val2) { alert(val1 + val2); } fn(1, 2);
|
用对象收编变量
如果定义大量验证函数, 会产生太多全局变量, 在团队开发中, 别人可能会定义相同的方法从而覆盖掉原有的一些验证功能, 很难察觉
所有将验证函数放在一个变量里保存, 减少被覆盖的风险, 如果变量被覆盖, 所有功能失效, 会很明显察觉到
1 2 3 4 5 6 7 8
| var CheckObject = { checkName: function() { }, checkEmail: function() { } }
|
对象的另一种形式
1 2 3
| var CheckObject = function() {} CheckObject.checkName = function() {} CheckObject.checkEmail = function() {}
|
以上对象无法复制一份, 使用new关键字新建的对象无法继承验证方法
真假对象
1 2 3 4 5 6 7 8 9
| var CheckObject = function() { return { checkName: function() {}, checkEmail: function() {} } }
var a = CheckObject() a.checkEmail()
|
每次执行CheckObject函数都会返回一个新对象, 这样每个人使用时就互不影响了
类也可以
1 2 3 4 5 6 7
| var CheckObject = function() { this.checkName = function() {} this.checkEmail = function() {} }
var a = new CheckObject() a.checkEmail()
|
prototype
新创建的对象都会对类的this上的属性进行复制, 每个新创建的对象都会有自己的一套方法, 这是很奢侈的, 可以用原型处理一下
1 2 3
| var CheckObject = function() {} CheckObject.prototype.checkName = function() {} CheckObject.prototype.checkEmail = function() {}
|
或者
1 2 3 4 5
| var CheckObject = function() {} CheckObject.prototype = { checkName: function() {}, checkEmail: function() {} }
|
上面两项不能混用, 否则后面会覆盖前面
链式调用
1 2 3 4 5 6 7 8 9 10 11 12
| var CheckObject = { checkName: function() { return this }, checkEmail: function() { return this } }
CheckObject.checkName().checkEmail()
|
或者使用类的原型对象
1 2 3 4 5 6 7 8 9 10 11 12
| var CheckObject = function() {} CheckObject.prototype = { checkName: function() { return this }, checkEmail: function() { return this } }
var a = new CheckObject() a.checkName().checkEmail()
|
prototype.js
一款JavaScript框架, 最大特点是对原生对象(如Function Array Object)的拓展
1 2 3 4 5 6 7 8 9 10
| Function.prototype.checkEmail = function() { }
var f = function() {} f.checkEmail()
var c = new Function() c.checkEmail()
|
以上方式不允许, 会污染原生对象Function, 导致别人创建的函数也会被你创建的函数污染, 造成不必要的开销, 但你可以抽象出一个统一添加方法的功能方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Function.prototype.addMethod = function(name, fn) { this[name] = fn }
var methods = function() {} var methods = new Function() methods.addMethod('checkName', function() { }) methods.addMethod('checkEmail', function() { }) methods.checkName() methods.checkEmail()
|
链式添加(函数式调用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Function.prototype.addMethod = function(name, fn) { this[name] = fn return this }
var methods = funciton() {}
methods.addMethod('checkName', function() {}).addMethod('checkEmail', function() {})
methods.addMethod('checkName', function() { return this }).addMethod('checkEmail', function() { return this }) methods.checkName().checkEmail()
|
换一种方式使用方法(类式调用)
1 2 3 4 5 6 7 8 9 10
| Function.prototype.addMethod = function(name, fn) { this.prototype[name] = fn return this }
var Methods = function() {} Methods.addMethod('checkName', function() {}).addMethod('checkEmail', function() {})
var m = new Methods() m.checkEmail()
|