作者:buddha覀mito_438 | 来源:互联网 | 2023-06-05 20:57
为什么突然讲这个呢?总结一下,这节讲的主要内容是:
- 使用装饰模式来为对象添加属性,或用于创建对象
- 尽可能使对象模块化(类化),可能是使用
this
关键字 的其中一种最佳实践
从课程讲的例子来看,装饰模式,顾名思义就是装饰对象。狭义来看,就是往对象上面添加属性,从而达到以一个函数来移除重复代码的目的。比如以下代码:
let amy = { location: 1 }
amy.location++
let ben = { location: 2 }
ben.location++
其构造过程(即location
属性的添加)可以通过装饰者模式来移除;而对 location
的操作可视为对象的行为,与面向对象的概念是很像的。上面的代码最终可以重构成下面这样,注意 this
关键字的应用:
let carlike = function(obj, location) {
obj.location = location
obj.move = move
return obj
}
let move = function() {
return this.location++
}
let amy = carlike({}, 1)
let ben = carlike({}, 2)
amy.move()
ben.move()
进一步重构发现,move
函数其实只是用于操作 carlike
生产出来的对象,放到全局里面不合理。因此,我们尝试把它放到 carlike
函数里。不过要注意,这样的代价是,carlike
每被调用一次,就会生成一个函数(绑定到 move
上的函数),会占据更多的内存。
let carlike = function(obj, location) {
obj.location = location
obj.move = function() {
this.location++
}
return obj
}
let amy = carlike({}, 1)
let ben = carlike({}, 2)
amy.move()
ben.move()
然而,我就发现,这个其实就是个很面向对象的简单类的构造:包括一个属性和方法。用 ES6 的 class
关键字即可轻松简明做到:
class Car {
constructor(location) {
this.location = location
}
move() {
this.location++
}
}
这解决了我以前很困惑的一个问题:ES6 中的类只是函数的一个扩展。我一直没明白什么意思。现在看来,更清楚了,class
说白了主要做了这样两件事:
- 确保
this
绑定到正确的对象上,这样你可以正常地按照 obj.method()
的方式来调用而不需管 this
的问题。从概念模型上讲,它应该是发生在构造函数之前,因为构造函数里就可以使用 this
关键字了 - 提供了定义对象方法的语法糖,背后做的事应该就是把你定义的函数绑定到对象上。因为对象实际上也只是一个函数,这也解释了为何类里即使引用同一个类的方法,也需要加
this.anotherMethod()
关键字