1.创建对象时,js引擎会将这个对象默认继承一个对象,这个对象就是原型对象
2. 如果函数作为普通函数调用prototype没有任何作用,当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过 __proto__ 来访问该属性原型对象就相当于一个公共的区域, 所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。
3. 原型链:实例对象( 通过__proto__ )与原型之间的链接
(person.__proto__ === Person.prototype)
4.继承的方式: 组合继承,寄生组合继承(这两个都是原型继承),class继承
// 组合继承
// 该方式核心是在子类的构造函数中通过Parent.call(this)继承父类的属性,然后改变子类的原型为new Parent() 来继承父类的函数。缺点是原型上多了不需要的父类属性,存在内存上的浪费。如下图1
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function() {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = new Parent()
const child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
// 寄生组合继承
// 以上继承实现的核心就是将父类的原型赋值给了子类,并且将构造函数设置为子类,这样既解决了无用的父类属性问题,还能正确的找到子类的构造函数。如下图2
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function() {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = child
const child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
// class 继承
// 子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)
class Parent {
constructor(value) {
this.val = value
}
getValue() {
console.log(this.val)
}
}
class Child extends Parent {
constructor(value) {
super(value)
this.val = value
}
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true