类和原型
JavaScript没有类,但是可以通过原型,以及ES6的语法糖class
模拟类的实现。
原型
原型是 JavaScript 对象相互继承特性的机制。
指向原型对象的属性是__proto__
,访问对象原型的标准方法是getPrototypeOf()
。
js
Object.getPrototypeOf(obj) === Object.prototype
obj.__proto__ === Object.prototype
区别与联系:
prototype
是构造函数上的属性__proto__
是对象上的非标准属性- 它俩指向同一个原型对象
原型对象本身是一个对象,故原型对象也会有它自己的原型,逐渐构成了原型链。null
是原型链的末尾。
继承
在传统的面向对象编程中,类是继承的基础。
JavaScript 中没有类,也就没有类的继承。
但可以基于原型链实现继承,是通过让一个对象继承另一个对象的属性和方法来实现的。
构造函数
对象类型 = 类 = 用于创建对象的模板。创建“对象类型”的方法是使用对象构造函数。
在上一节示例代码中,Object
是obj
的构造函数.
定义一个构造函数:
js
function Box(value){ //首字母大写是一种约定实践,不是必须
this.value = value
}
在构造函数中,this
指代被创建的新对象实例。
js
Object.prototype.constructor === Object === obj.constructor
上述等式不能推导出 obj === Object.prototype
,仅仅是不同对象有个 constructor
属性指向相同构造函数 Object
new
运算符
创建一个具有构造函数的对象类型的实例。
js
new Constructor[([arguments])]
(arguments)
是可选的,new Object
等价于new Object()
。
new
运算符做了以下事情:
js
var obj = {}
Object.setPrototypeOf(obj, Constructor.prototype)
var result = Constructor.apply( obj, arguments ) || obj
result.constructor = Constructor
return result
在实现继承这个概念上,JavaScript是鸭式辨型的。
换句话说,只要能达成和继承一样的效果,不管用的什么方法,都是实现了“继承”。
鸭式辨型:如果看起来像、走起路来像、叫起声来像鸭子,那么它就是鸭子
类
js
class Box {
constructor(value) {
this.value = value;
}
// 在 Box.prototype 上创建方法
getValue() {
return this.value;
}
}
类是构造函数的语法糖,这意味着你仍然可以修改 Box.prototype
来改变所有实例的行为。