js原型与原型链

简化总结

1、每一个函数默认都有prototype(原型)属性
2、这个默认的原型里面有一个默认的属性constructor
指向他的构造函数
(此时涉及到原型的重定向)
3、每一个对象都有__proto__属性,
这个属性指向当前实例所属类的原型
(不确定所属类,就指向Object.prototype)
(应为所有对象都是Object类的实例)

1.原型
在JavaScript中,每个函数都会天生自带一个prototype属性,
这个属性指向函数的原型对象,
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到
这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。
每一个对象也天生自带一个属性__proto__,
属性值是当前实例所属类的原型(prototype)。
原型对象中有一个属性constructor, 指向函数对象。

2.何为原型链
在JavaScript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。

当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined。

我们可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性;
使用in检查对象中是否含有某个属性时,
如果对象中没有但是原型中有,也会返回true

Object是JS中所有对象数据类型的基类(最顶层的类)在Object.prototype上__proto__这个属性是null

在这里插入图片描述

Object Function的关系

console.log(Object.__proto__ === Function.prototype) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__ === null) // true

Object.__proto__ === Function.prototype
true
Function.__proto__ === Function.prototype
true
Function.prototype.__proto__ === Object.prototype
true

Object.__proto__ === Function.prototype,
Function.__proto__ === Function.prototype, 
Function.prototype.__proto__ === Object.prototype

.实例对象的constructor属性指向其构造函数, 
  Object.constructor === Function,
 Function.constructor === Function.
1. 首先Object和Function都是构造函数,
2. 而所有的构造函数的都是Function的实例对象. 
3. 因此Object是Function的实例对象
6.  因此 Object.proto ===Function.prototype,
7. Function.__proto__===Function.prototype,
8. Function.prototype.proto === Object.prototype
9. 当我们访问一个属性值的时候,
10.  它会沿着原型链向上查找, 
11. 直到找到或者到Object.prototype.proto(为null)截止.

Object.prototype.constructor
function Object() { [native code] }
这只不过是JS的语言设计者为了概念一致,
把祖宗对象的constructor指向了Object而已。
祖宗对象之前是什么呢?
Object.prototype.proto
null
道生一,一生二。
道是无。

object function关系

我们知道一般任何对象都是Object的instance,
因为原型链的顶端都指向Object.prototype。
那么Object本身是什么?Object也是个函数,
而任何函数都是Function的实例对象,
比如Array,String,当然Object也包括在内
,它也是Function的实例,即:

Object.__proto__ === Function.prototype;
Object instanceof Function === true

Function.__proto__.__proto__ === Object.prototype;
Function instanceof Object === true

Object instanceof Function === true
Function instanceof Object === true

我们知道Object.prototype是原型链的root。但首先,现在世界上还没有Object,更没有Object.prototype。现在只有个特殊的对象,姑且称它为root_prototype,里面定义了些基本的field和method比如toString之类的,以后我们要让所有的原型链都最终指向它。注意它没有原型,它的__proto__是null,这也是它和所有其它JavaScript对象的区别,使它与众不同,能有资格成为原型链的root。
然后定义Function。先看Function的prototype,我们只要知道这是一个特殊的对象,它的原型__proto__指向刚才的root_prototype,就是说Function.prototype.__proto__ === root_prototype,这样它就算连上了原型链的root。
上面已经讲过了,Function也是个对象,也有__proto__,指向Function自己的prototype,所以说白了Function也是个奇葩,是JavaScript里规定的一个特殊的东西。而Function.prototype的原型__proto__继续指向root_prototype,所以Function也连上了原型链root。
所有的函数,什么Array之类的,包括Object也是函数,都是继承Function的,就是说,任意函数foo.__proto__ === Function.prototype,所以我们自然有Object instanceof Function。
然后再看Object,它本来就是个函数而已,和其它函数没什么区别,都继承了Function。可是现在最关键的一步是,强行设定让Object.prototype = root_prototype,这样Object.prototype就成了原型链的root!注意这里的逻辑,是先有了root_prototype,然后规定Object.prototype等于它,这一步是人为规定的,这就是Object的特殊之处。
好了现在Object.prototype === root_prototype了,成了所有对象原型链的root。那么由第3步的结论,Function也是对象,是连上了root_prototype的,而现在root_prototype给Object.prototype了,那Function自然就是instanceof Object。

Object之所以特殊,就是因为Object的prototype被设定为了root_prototype,仅此而已;
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值