关于JS的原型链自己也简单总结一下!
首先先上一张图,我第一次看这张图的时候原本就懵的我更懵了。可是我想说的是,尽管再懵,也还是要慢慢自己理解,最后才能拨开云雾见天日。
目前看不清除图没关系。先解释两个属性的概念
1. 概念
prototype:是函数所独有的
__proto:是对象所独有的。PS,为什么Animal实例也有这个属性呢,因为再js的宇宙里万物皆对象,包括函数。这个属性会指向该原型对象
constructor:每个原型都有一个constructor属性指向关联的构造函数
这里有几个关键点记住就行了。
1. 只有函数才有prototype,又叫函数的原型对象,而实例只有__proto__
2.函数是Function的实例,函数的prototype是Object的实例
3.Function.proto 和 Function.prototype相等
4.Object.prototype.__proto__指向null
2.原型链实现new
总结起来4个步骤
- 创建对象obj
- 将对象obj的**proto与构造函数Animal的prototype**连接
- 执行构造函数
- 返回对象obj
function Animal() {
this.name = 'Animal name'
}
Animal.prototype.getName = function () {
return this.name
}
function myNew(fn) {
let obj = {}
obj.__proto__ = fn.prototype
fn.apply(obj, [])
return obj
}
let newAnimal = myNew(Animal)
console.log(newAnimal.getName()) // Animal name
3.使用prototype模拟继承
总结就是:只要将父类的实例赋值给子类的prototype属性就行了,然后子类就可以使用父类的方法和属性了
function Animal() {
this.name = 'Animal name'
}
Animal.prototype.getName = function () {
return this.name
}
function dog() {
}
// 将父类的实例赋值给子类的prototype属性
dog.prototype = new Animal()
console.log(new dog().getName()) // Animal name
补充apply实现继承
function Animal() {
this.name = 'Animal name'
}
Animal.prototype.getName = function () {
return this.name
}
function dog() {
// 可以访问父类的属性和方法了
Animal.apply(this, [])
this.dogName = this.name
}
let newDog = new dog()
console.log(newDog.dogName) // Animal name