JS的原型与原型链
原型prototype
在JS中每个函数都有一个prototype属性(显式原型属性),它默认指向一个Object空对象,而这个Object空对象就是我们说的原型对象。
在原型对象中有constructor属性, 它指向函数对象(套娃)
function Fn(){
}
console.log(Fn.prototype)
console.log(Fn.prototype.constructor === Fn)//true
了解了原型对象那么我们可以像原型对象当中添加属性,这样该函数的所有实例都会自动拥有该函数原型对象中的属性
function Fn(){
}
console.log(Fn.prototype)
console.log(Fn.prototype.constructor === Fn)
Fn.prototype.GirlFriend = function(){
console.log("做梦呢?你哪来的女朋友!")
}
let fn = new Fn()
fn.GirlFriend()//做梦呢?你哪来的女朋友!
每个函数都有prototype属性(显示原型),而每一个实例对象则有一个**__proto__属性(隐式原型)**。
function Fn(){
}
console.log(Fn.prototype)
console.log(Fn.prototype.constructor === Fn)
Fn.prototype.GirlFriend = function(){
console.log("做梦呢?你哪来的女朋友!")
}
let fn = new Fn()
fn.GirlFriend()
console.log(fn)
实例对象的隐式原型的值(地址值)为其对应构造函数的显式原型的值(地址值)
function Fn(){
}
console.log(Fn.prototype)
console.log(Fn.prototype.constructor === Fn)
Fn.prototype.GirlFriend = function(){
console.log("做梦呢?你哪来的女朋友!")
}
let fn = new Fn()
fn.GirlFriend()
console.log(fn)
console.log(fn.__proto__ === Fn.prototype)//true
总结:
1.函数的prototype属性在定义函数时自动添加,默认指向一个空的Object对象
2.实例对象的__proto__属性在创建对象时自动添加,默认值是其对应构造函数的prototype属性值
3.在ES6前我们能直接操作显示原型,而不能操作隐式原型。(兼容IE,ES6中我们可以操作隐式原型)
原型链
原型链的查找循序
当我们访问某个对象属性的时候,首先在自身属性中查找,找到返回。
如果没有找到则沿着__proto__原型链向上查找,找到返回。
如果还是没有找到则返回undefined。
function Fn(){
this.name = "桥本环奈"
}
Fn.prototype.age = 18
let fn = new Fn()
console.log(fn.name)//自身属性中有name,返回
console.log(fn.age)//自身属性未找到寻找__proto__,找到age返回
console.log(fn.leg)//自身属性没有,__proto__也没找到,返回undefined
console.log(Object.prototype.__proto__)//null
原型链三点注意事项
1、函数的显示原型指向的对象默认是空Object实例对象,但Object不满足
console.log(Object)
console.log(Object.prototype)
console.log(Object.prototype.__proto__)
console.log(Object.prototype instanceof Object)//false
使用instanceof可以明显的看出Object的显示原型对象不在Object.prototype的原型链上
2、所有函数都是Function的实例,包含Function
console.log(Function.__proto__ === Function.prototype)//true
3、Object的原型对象是原型链尽头
console.log(Object.prototype.__proto__) // null
其实在第一点就能看出在object的显示原型中已经不存在__proto__属性了!