【JavaScript重中之重】关于原型与原型链,prototype和__proto__的理解

说到原型链,必须先抛出这张图了?
原型链
首先来梳理下这张图的信息:

  1. 图中有三个函数和四个实例对象:
    三个函数:function Foo(){}、Object、Function
    四个实例对象:f1、f2、o1、o2

  2. 函数Foo是通过new Function方式创建的,因此Foo的__proto__属性指向Function.prototype,即Foo.__proto__===Function.prototype

  3. 函数Foo有一个prototype属性:Foo.prototype,该属性有一个constructor属性,指向函数Foo本身,即Foo.prototype.constructor===Foo,Foo.prototype还有一个__proto__属性,指向Object的prototype,即Foo.prototype.__proto__===Object.prototype

  4. 函数Foo的实例对象f1和f2有一个__proto__属性,指向函数Foo的prototype属性,即f1.__proto__===Foo.prototypef2.__prototype===Foo.prototype

  5. Object是通过new Function方式创建的,因此Object的__proto__属性指向Function.prototype,即Object.__proto__===Function.prototype

  6. Object有一个prototype属性:Object.prototype,该属性有一个constructor属性,指向Object本身,即Object.prototype.constructor===Object,Object.prototype也有个__proto__属性,指向null,即Object.prototype.__proto__===null

  7. Object的实例对象o1和o2有一个__proto__属性,指向Object的prototype属性,即o1.__proto__===Object.prototypeo2.__proto__===Object.prototype

  8. Function是通过new Function方式创建的,因此Function的__proto__属性指向Function.prototype,即Function.__proto__===Function.prototype

  9. Function有一个prototype属性:Function.prototype,该属性有一个constructor属性,指向Function本身,即Function.prototype.constructor===Function;Function.prototype也有一个__proto__属性,指向Object.prototype,即Function.prototype.__proto__===Object.prototype

总结一下重点:

  1. 函数有两个属性:__proto__和prototype
  2. Object.__proto__===Function.prototype
  3. Function.__proto===Function.prototype
  4. Object.prototype.__proto__===null

原型链的基本思想是:利用原型让一个引用类型继承另一个引用类型的属性和方法。JavaScript高级程序设计中有关于构造函数、原型和实例关系的描述:

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。

JavaScript中,一切引用类型和null皆对象。每个实例对象(object )都有一个私有属性(称之为__proto__)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象(__proto__) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。但是对象也分普通对象和函数对象。普通对象的__proto__指向Object的prototype,而函数对象的__proto__指向Function的prototype。

javaScript的内置对象Array、Boolean、String、Number、Date、RegExp、Function、Object、Promise等都是函数对象,而JSON、Math等不是函数对象。即:

Array.__proto__===Function.prototype
Boolean.__proto__===Function.prototype
String.__proto__===Function.prototype
Number.__proto__===Function.prototype
Date.__proto__===Function.prototype
RegExp.__proto__===Function.prototype
Function.__proto__===Function.prototype
Object.__proto__===Function.prototype
Promise.__proto__===Function.prototype

JSON.__proto__===Object.prototype
Math.__proto__===Object.prototype

所以关于__proto__和prototype只要记下以下几点即可:

  1. __proto__是所有对象都有的,它是对象的原型,原型链就是靠它形成的。查看对象的__proto__来得知自己是基于什么prototype被制造的。而prototype只有函数(准确地说是构造函数)才有的,它也是一个对象(普通对象),它的作用是:构造函数new对象的时候,告诉构造函数新创建的对象的原型是谁。
  2. 普通对象的__proto__指向Object的prototype,函数对象的__proto__指向Function的prototype。
  3. Object.prototype.__proto__===null
  4. 当访问一个实例属性时,首先会在该实例中搜索该属性,如果没有找到,则会继续搜索实例的原型,如果还是没有找到,则会在实例的原型的原型上找,搜索过程会沿着原型链向上查找,直到找到或找到Object.prototype为至。
  5. A instanceof B即判断A.__proto__===B.prototype的返回值

来几个例子理解下吧:

function F(){};
var o = {};
                
typeof F;                          //==> function
typeof o;                          //==> object
typeof F.prototype;                //==> object,函数的prototype是一个对象,所以返回object
typeof o.prototype;                //==> undefinded,只有函数才有prototype,o是一个对象,没有该属性
typeof new F;                      //==> object,通过new实例化了一个对象
typeof (new F).prototype;          //==> undefined,对象是没有prototype属性的
typeof (new F).__proto__;          //==> object,实例化出来的是一个普通对象,它的__proto__指向Object
typeof F.__proto__;                //==> function
typeof o.__proto__;                //==> object
typeof Object;                     //==> function
typeof Function;                   //==> function
typeof (new Function).prototype;   //==> object
typeof (new Function).__proto__;   //==> function
typeof (new Object).prototype;     //==> undefined
typeof (new Object).__proto__;     //==> object
typeof Object.prototype;           //==> object
typeof Object.__proto__;           //==> function
typeof Function.prototype;         //==> function
typeof Function.__proto__;         //==> function
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值