谈谈你原型链的理解?
函数与对象的关系?
原型的类别?
原型的概念?
原型链的概念?
关于Function和Object?
原型、构造函数、实例、原型链?
instanceof?
继承?
1. 函数与对象的关系?
- javascript 中,一切皆是对象
- 函数是对象,对象是通过函数创建的
2. 原型的类别?
- 显示原型: prototype, 每个函数function独有的属性
- 隐示原型: _ _ proto _ _,每个对象都具有的属性
3. 原型的概念?
- 所有的实例对象都有一个属性_ _ proto _ _
- 所有的构造函数都有一个属性prototype
- 所有实例对象的_ _ proto _ _ 指向它构造函数的prototype
4. 原型链的概念?
- 概念: 当访问某个对象的属性时,先在该对象本身属性上找,找不到,则会去其隐式原型_ _ proto _ 上查找(即它的构造函数的prototype), 如果还没找到就会去「它构造函数的prototype的隐士原型 _ proto _ _上查找」,这样一层一层向上查找就会形成一个链式结构,我们称之为“原型链”
- 作用
1. 数据共享,节省内存空间
2. 实现继承
5. 关于Function和Object?
- Function是最顶层的「构造器」,构建了系统中「所有对象」
- 「函数」也是Function构造的
1. 函数.__proto__ === Function.prototype
- 「Object」也是Function构造的
2. Object.__proto__ === Function.prototype
- 「函数本身」也是Function构造的
3. Function.__proto__ === Function.prototype
- Object 是最顶层的「对象」,它的_ _ proto _ _指向null
1. 所有「对象」 都继承Object的原型
函数.prototype.__proto__ ==== Object.prototype
Function.prototype.__proto__ ==== Object.prototype
2. Object也是被Function构造出来的
Function instanceof Function ===> true
Function instanceof Object ===> true
Object instanceof Object ===> true
Object instanceof Function ===> true
3. Object.prototype, 它的_ _ proto _ _指向null
Object.prototype.__proto__ === null
6. 原型、构造函数、实例?
术语: 只要是对象,它就是一个实例
术语: 任何函数都有prototype属性(js声明时自动加的)
术语: 函数都是对象, 所以他也有__propto__
1. 实例: 构造函数通过new 运算符,来生成一个实例
2. 构造函数: 任何一个函数被new, 该函数就是构造函数
3. 原型对象: 构造函数的pototype指向的对象
4. 构造器constructor: 通过它区分原型对象被哪个构造函数引用
```
1. 函数.prototype: 每个函数都有prototype
2. 对象.__proto__: 每个对象都有__proto__
3. 函数.__proto__: 每个「函数」都是「对象」
4. 函数.prototype.__proto__: 函数的prototype是对象
```
7. instanceof?
- 概念: 判断「一个构造函数的prototype」属性所指向的对象是否在「另一个被检测对象」的原型链上
8.继承:
1. 借助构造函数实现:(部分继承)
<!--原理:改变this的指向-->
<!--父级在子级函数中执行,且修改父级构造函数的指向-->
function Parent1() {
this.name = 'parant1'
}
function Child1() {
Parent1.call(this);
this.type = 'child1'
}
console.log(new Child1)
<!--缺点: Child1继承不了Parent1的原型对象上的方法-->
2. 借助原型链实现继承:
<!--原理:找属性name, Child2自己没有,找Child2.prototype, 此时Child2.prototype = new Parent2(), 可以找到name-->
function Parent2() {
this.name = 'parant2'
}
function Child2() {
this.type = 'child2'
}
Child2.prototype = new Parent2()
console.log(new Child2)
<!--缺点: 改一个对象属性另一个属性也被改变了,原型对象是共用的-->
3. 组合方式(构造函数 + 原型链):
function Parent3() {
this.name = 'parant3'
}
function Child3() {
Parent3.call(this)
this.type = 'child3'
}
Child3.prototype = new Parent3()
<!--缺点: 父级的构造函数执行了两次-->
<!--构造函数复用-->
<!--优化后-->
Child3.prototype = Parent3.prototype
<!--缺点: 共用一个原型对象,原型对象不知道是哪个构造函数引用的-->
console.log(new Child3())
4. 组合继承的完美写法
function Parent4() {
this.name = 'parant4'
}
function Child4() {
Parent3.call(this)
this.type = 'child4'
}
<!--隔离-->
Child4.prototype = Object.create(Parent4.prototype)
<!--写一个自己的constructor-->
Child4.prototype.constructor = Child4
6. class extends 继承
```
class People {
constructor() {
this.name = name
}
active() {
console.log(`$this.name`)
}
}
class Teacher extends People {
constructor(name) {
super(name)
this.time = time
}
active() {
console.log(`${this.name}`)
}
}
class Doctor extends People {
constructor(name) {
super(name)
this.start = start
}
eat() {
console.log(`${this.name}`)
}
}
```