原型
向实例对象内添加方法 在构造函数体内 直接向实例对象添加方法,这个行为不好会产生问题,
function Person(name, age) {
this.name = name
this.age = age
this.sayHi = function () { console.log('hello') }
}
var p1 = new Person('aa', 18)
var p2 = new Person('bb', 20)
问题:
把方法书写在构造函数体内。每次创建实例的时候,都会创建一个函数数据类型,多个函数方法,一模一样,但是占据了多个存储空间
解决问题1:用到原型
-
概念:每一个构造函数天生自带一个prototype属性,是一个对象数据类型, 原型对象
-
概念:每一个对象天生自带一个属性__proto__,指向所属构造函数的prototype。
function Person() {}
Proson.prototype.a = 100
Proson.prototype.b = 200
//p1所属的构造函数就是 Person
//p1.__proto__ 指向 Person.prototype
var p1 = new Person()
console.log(p1.__proto__ === Person.prototype) //true
- 概念:当访问对象成员的时候,首先在自己身上查找,如果没有,自动去到
__proto__上查找
对象的__proto__属性,指向所属构造函数的prototype
function Person() {}
Proson.prototype.a = 100
Proson.prototype.b = 200
var p1 = new Person()
//当访问p1.a的时候
//p1自己没有a, 会自动去找 __protp__ 上查找
//又因为 p1 自己的 __protp__ 就是 Person.prototype
//所以,其实是去Person.prototype上查找, 即:Person.prototype.a
console.log(p1.a)
如何解决问题: 把需要添加给实例的方法,放在构造函数的原型(prototype)上,就可以有实例进行访问使用。
应用:
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function () { console.log('hello') }
var p1 = new Person('Jack', 18)
var p2 = new Person('Rose', 20)
//p1.__proto__ 和 p2.__proto__是一个对象空间,指向Person的prototype
//p1.sayHi 和 p2.sayHi 是一个
console.log(p1.sayHi === p2.sayHi) //true
总结:
- 什么是原型:构造函数天生自带一个prototype
- 作用:有构造函数添加方法,专门给实例对象使用
原型链
function Person() {}
var p1 = new Person()
问题1:实例对象身上的 __proto__ 指向谁
- 指向所属构造函数的 prototype
p1.__proto__指向 Person.prototype
问题2:Person.prototype 的__proto__ 指向谁
- Person.prototype 所属构造函数是谁?
- 因为Person.prototype是一个对象数据类型(Object),在 JS 内所有的 Object 数据类型都是属于 Object 这个内置构造函数
- 所以 Person.prototype 是属于 Object 这个内置构造函数,
Person.prototype.__proto__指向 Object.prototype
问题3:Person(函数/对象)的 __proto__ 指向谁
- Person 是一个函数, 函数本身也是一个对象,就会有
__proto__,在 JS 内所有的函数都是内置构造函数 Function 的实例Person.__proto__指向 Function.prototype
问题4:Object.prototype 的__proto__ 指向谁
Object.prototype是一个对象数据类型,属于 Object 这个内置构造函数- 注意:
Object.prototype在 JS 内叫做顶级原型,不在有__proto__- 所以,
Object.prototype__proto__指向 null
问题5:Object 的__proto__ 指向谁
Object是内置构造函数(函数对象),属于内置构造函数 Function 的实例- 所以,
Object.__proto__指向 Function.prototype
问题6:Function.prototype 的__proto__ 指向谁
- Function.prototype 也是一个对象,属于 Object 这个内置构造函数
Function.prototype.__proto__指向 Object.prototype
问题7:Function 的__proto__ 指向谁
- Function 也是一个内置构造函数,也是一个函数
- 在 JS 内,所有的函数都是属于内置构造函数 Function 的实例
- Function 自己是自己的构造函数,自己是自己的实例对象
原型链定义:
用__proto__串联起来的对象链状结构
每一个对象数据类型,都有一个属于自己的原型链
作用:为了访问对象成员
对象访问机制: 当需要访问对象成员的时候,
- 首先在自身查找,如有有直接使用
- 如果没有,自动去
__proto__上查找- 如果还没有,再去
__proto__上查找- 直到 Object.prototype 都没有,那么返回 undefined