电话里被面试官被问到了,自己平时工作中不怎么用到,答的很含糊,所以回头复习来一下。简单记录一下,方便哪天忘了再回来看看......先上这张经典图
js中万物都是对象,而对象具有__proto__属性(隐式原型链),一个对象的隐式原型指向构造该对象的构造函数的原型,保证了实例可以访问到构造函数原型中定义的属性跟方法
Function是个特殊的对象,除了有上面的__proto__属性之外,还有自己特有的属性--原型属性(prototype),prototype是一个指针,指向一个对象,而这个对象包含所有实例共享的属性和方法(这个对象叫做原型对象)。原型对象有__proto__属性,还有另外一个属性constructor,这个属性是也是一个指针,指向原构造函数
null最大,下来就是Object.prototype(一切对象都有__proto__),接下来就是Function.prototype(FuntionArrayObjectDateString构造函数这些都是函数原型的实例),接下来创建的构造函数或者其他类型的实例,都是继承这几大类型的公共属性跟方法
暂时把对象分为两类
普通对象:就是不是new 出来的对象,他只有隐式原型属性__proto__,上图
原型对象:就是构造函数的prototype{
1. 有__proto__,看下面代码不难发现这个原型的__proto__指向的是object
2. constructor,这个constructor指向的地址是这个构造函数。
}
函数对象:Function、Object、Array、Date、String、自定义函数 。拥有__proto__、prototype属性(指向原型对象)。
以Array为例,他是函数对象,是Function的实例对象,Array是通过new Function创建出来的。因为Array是Function的实例,
所以Array.__proto__ ===Function.prototype
Array.prototype.__proto__==Object.prototype,Array的原型的隐式原型列最终指向的object,再网上找就是null
原型链基本思路:
利用原型让一个引用类型继承另一个引用类型的属性和方法。
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针(constructor),而实例对象都包含一个指向原型对象的内部指针(__proto__)。如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针(__proto__),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型的实例……这就构成了实例与原型的链条。
公共的属性跟方法可以放在原型中。原型链由各个子对象的__proto__属性连续引用的结构。
原型相关api
1.判断对象的属性是自有还是共有:
判断自由:obj.hasOwnProperty(“属性名”) true说明自有,如果false,也可能在原型链上也可能真的没有
判断公有:1. ”属性名“ in 对象
2. if(obj["属性名"])如果有效
判断共有固定套路:
function a(){}
a.prototype.name='xk'
var test=new a();
if(test.hasOwnProperty('name')){
console.log('自由属性');
}else if('name' in test){
console.log('共有属性');
}else{
console.log('没有该属性')
}
2.获取任何子对象的原型
obj.__proto__
Object.getPrototypeOf(子对象)
3.判断父对象是否在子对象的原型链上
父级对象.isPrototypeOf(子对象) 强调:isPrototypeOf不仅找直接父级,而是找整个原型链