访问者模式

访问者模式: 针对于对象结构中的元素, 定义在不改变该对象的前提下访问结构中元素的新方法.

核心思想

在不改变操作对象的同时, 为它添加新的操作方法, 来实现对操作对象的访问.

对象访问器

举例: 像处理数组一样处理对象, 为对象添加push, pop方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var Visitor = (function () {
return {
// 截取方法
splice: function () {
// splice方法参数, 从原参数的第二个参数开始算起
var args = Array.prototype.splice.call(arguments, 1)
// 对第一个参数对象执行splice方法
return Array.prototype.splice.apply(arguments[0], args)
},
// 追加数据方法
push: function () {
// 强化类数组对象, 使他拥有length属性
var len = arguments[0].length || 0
// 添加的数据从原参数的第二个参数算起
var args = this.splice(arguments, 1)
// 校正length属性
arguments[0].length = len + arguments.length - 1
// 对第一个参数对象执行push方法
return Array.prototype.push.apply(arguments[0], args)
},
// 弹出最后一次添加的元素
pop: function () {
// 对第一个参数对象执行pop方法
return Array.prototype.pop.apply(arguments[0])
},
}
})()

测试

1
2
3
4
5
6
var a = new Object()
console.log(a.length) // undefined
Visitor.push(a, 1, 2, 3, 4, 5) // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, length: 5 }
Visitor.push(a, 6, 7, 8) // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, length: 8 }
Visitor.pop(a) // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, length: 7 }
Visitor.splice(a, 2) // { '0': 1, '1': 2, length: 2 }

刚创建对象a时, a是没有length属性的, 当调用了push或者pop, splice时数组内部的实现会赋予或修改length属性