目录
1. 原型(prototype)
每一个函数都会创建一个prototype属性(指向原型对象),这个属性是一个对象(默认是一个空的实例对象,没有自己设置的方法和属性),包含其引用类型的实例共享的方法和属性(原型对象的优点),所有原型对象都包含一个constructor属性(指回这个函数)。
// 构造函数声明可以是函数表达式和函数声明(存在函数提升)
// function Person() {
// }
// let Person = function() {
// }
function Person() {
}
console.log(typeof Person.prototype);
// 默认指向一个Object空对象(没有我们的属性)
console.log(Person.prototype);
// 原型对象中有一个属性constructor, 它指向函数对象
console.log(Person.prototype.constructor === Person);
//给原型对象添加属性(一般是方法) ===>实例对象可以访问
Person.prototype.singSong = function() {
console.log('song')
}
let p = new Person
p.singSong()
2.显式原型与隐式原型
1. 每个函数function都有一个prototype,即显式原型(属性),默认值是一个空对象,在定义函数时自动添加的
2. 每个实例对象都有一个__proto__,可称为隐式原型(属性),默认值是其构造函数的prototype值,创建对象时自动添加的
3. 对象的隐式原型的值为其对应构造函数的显式原型的值
function Person() {
}
// 默认指向一个Object空对象(没有我们的属性)
console.log(Person.prototype);
// 原型对象中有一个属性constructor, 它指向函数对象
console.log(Person.prototype.constructor === Person);//true
// 每个实例对象都有一个__proto__
let p = new Person() // 内部语句: this.__proto__ = Fn.prototype
console.log(p.__proto__);
// 对象的隐式原型的值为其对应构造函数的显式原型的值
console.log(p.__proto__ === Person.prototype);//true
// 正常的原型链都会终止于Object原型对象,而Object原型的原型是null
console.log(Person.prototype.__proto__ === Object.prototype);//true
console.log(Person.prototype.__proto__.constructor === Object); //true
console.log(Person.prototype.__proto__.__proto__ === null);//true
注意:原型对象,构造函数和实例是三个不同的对象。实例通过隐式原型链接到原型对象,但实际上指向藏特性[[Prototype]] 。
3.原型链
在访问一个对象的属性时,
* 先在自身属性中查找,找到返回
* 如果没有, 再沿着__proto__这条链向上查找, 找到返回
* 如果最终没找到, 返回undefined
* 别名: 隐式原型链
* 作用: 查找对象的属性(方法)
console.log(Object)
console.log(Object.prototype)
console.log(Object.prototype.__proto__)
function Fn() {
this.test1 = function () {
console.log('test1()')
}
}
console.log(Fn.prototype)
Fn.prototype.test2 = function () {
console.log('test2()')
}
var fn = new Fn()
fn.test1()
fn.test2()
console.log(fn.toString())
console.log(fn.test3)//原型链查找方式:如果最终没找到, 返回undefined
// fn.test3() Uncaught TypeError: fn.test3 is not a function
/*
1. 函数的显示原型指向的对象默认是空Object实例对象(但Object函数不满足)
*/
console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false
console.log(Function.prototype instanceof Object) // true
/*
2. 所有函数都是Function的实例(包含Function)
*/
console.log(Function.__proto__===Function.prototype)
/*
3. Object的原型对象是原型链尽头
*/
console.log(Object.prototype.__proto__) // null
注意:Object.prototype并不是Object的实例对象
图解:
4.相关问题
注意点:
1. 读取对象的属性值时: 会自动到原型链中查找
2. 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
3. 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上
instanceof理解Object与Function之间的关系: (互为对方的实例,且自己是自己的实例)
console.log(Object instanceof Function) // true
console.log(Object instanceof Object) // true
console.log(Function instanceof Function) // true
console.log(Function instanceof Object) // true