用生命谱写代码的赞歌

0%

JavaScript基础篇

本系列出自于《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()