理解prototype、proto和constructor的关系javascript里的关系又多又乱。作用域链是一种单向 -零配件导航
稀土掘金 稀土掘金
Rays77
995 阅读4分钟

前面的话

  javascript里的关系又多又乱。作用域链是一种单向的链式关系,还算简单清晰;this机制的调用关系,稍微有些复杂;而关于原型,则是prototype、proto和constructor的三角关系。本文先用一张图开宗明义,然后详细解释原型的三角关系

 

图示

proto

 

概念

  上图中的复杂关系,实际上来源就两行代码

function Foo(){};
var f1 = new Foo;

【构造函数】

  用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数

【实例对象】

  通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象

function Foo(){};
var f1 = new Foo;
var f2 = new Foo;
console.log(f1 === f2);//false

【原型对象及prototype】

  构造函数有一个prototype属性,指向实例对象的原型对象。通过同一个构造函数实例化的多个对象具有相同的原型对象。经常使用原型对象来实现继承

复制代码

function Foo(){};
Foo.prototype.a = 1;
var f1 = new Foo;
var f2 = new Foo;

console.log(Foo.prototype.a);//1
console.log(f1.a);//1
console.log(f2.a);//1

复制代码

【constructor】

  原型对象有一个constructor属性,指向该原型对象对应的构造函数

function Foo(){};
console.log(Foo.prototype.constructor === Foo);//true

  由于实例对象可以继承原型对象的属性,所以实例对象也拥有constructor属性,同样指向原型对象对应的构造函数

function Foo(){};
var f1 = new Foo;
console.log(f1.constructor === Foo);//true

【proto】

  实例对象有一个proto属性,指向该实例对象对应的原型对象

function Foo(){};
var f1 = new Foo;
console.log(f1.__proto__ === Foo.prototype);//true

 

说明

  概念介绍完了,现在对图示的关系进行详细说明

function Foo(){};
var f1 = new Foo;

 

【第一部分: Foo】

  实例对象f1是通过构造函数Foo()的new操作创建的。构造函数Foo()的原型对象是Foo.prototype;实例对象f1通过__proto__属性也指向原型对象Foo.prototype

function Foo(){};
var f1 = new Foo;
console.log(f1.__proto === Foo.prototype);//true

  实例对象f1本身并没有constructor属性,但它可以继承原型对象Foo.prototype的constructor属性

function Foo(){};
var f1 = new Foo;
console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true
console.log(f1.hasOwnProperty('constructor'));//false

  下图是实例对象f1的控制台效果

 

【第二部分: Object】

  Foo.prototype是f1的原型对象,同时它也是实例对象。实际上,任何对象都可以看做是通过Object()构造函数的new操作实例化的对象

  所以,Foo.prototype作为实例对象,它的构造函数是Object(),原型对象是Object.prototype。相应地,构造函数Object()的prototype属性指向原型对象Object.prototype;实例对象Foo.prototype的proto属性同样指向原型对象Object.prototype

function Foo(){};
var f1 = new Foo;
console.log(Foo.prototype.__proto__ === Object.prototype);//true

  实例对象Foo.prototype本身具有constructor属性,所以它会覆盖继承自原型对象Object.prototype的constructor属性

function Foo(){};
var f1 = new Foo;
console.log(Foo.prototype.constructor === Foo);//true
console.log(Object.prototype.constructor === Object);//true
console.log(Foo.prototype.hasOwnProperty('constructor'));//true

  下图是实例对象Foo.prototype的控制台效果

  如果Object.prototype作为实例对象的话,其原型对象是什么,结果是null。私以为,这可能也是typeof null的结果是'object'的原因之一吧

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

 

【第三部分: Function】

 

 

  前面已经介绍过,函数也是对象,只不过是具有特殊功能的对象而已。任何函数都可以看做是通过Function()构造函数的new操作实例化的结果

  如果把函数Foo当成实例对象的话,其构造函数是Function(),其原型对象是Function.prototype;类似地,函数Object的构造函数也是Function(),其原型对象是Function.prototype

function Foo(){};
var f1 = new Foo;
console.log(Foo.__proto__ === Function.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true

  原型对象Function.prototype的constructor属性指向构造函数Function();实例对象Object和Foo本身没有constructor属性,需要继承原型对象Function.prototype的constructor属性

复制代码

function Foo(){};
var f1 = new Foo;
console.log(Function.prototype.constructor === Function);//true
console.log(Foo.constructor === Function);//true
console.log(Foo.hasOwnProperty('constructor'));//false
console.log(Object.constructor === Function);//true
console.log(Object.hasOwnProperty('constructor'));//false

复制代码

  所有的函数都可以看成是构造函数Function()的new操作的实例化对象。那么,Function可以看成是调用其自身的new操作的实例化的结果

  所以,如果Function作为实例对象,其构造函数是Function,其原型对象是Function.prototype

console.log(Function.__proto__ === Function.prototype);//true
console.log(Function.prototype.constructor === Function);//true
console.log(Function.prototype === Function.prototype);//true

  如果Function.prototype作为实例对象的话,其原型对象是什么呢?和前面一样,所有的对象都可以看成是Object()构造函数的new操作的实例化结果。所以,Function.prototype的原型对象是Object.prototype,其原型函数是Object()

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

  第二部分介绍过,Object.prototype的原型对象是null

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

 

总结

  【1】函数(Function也是函数)是new Function的结果,所以函数可以作为实例对象,其构造函数是Function(),原型对象是Function.prototype

  【2】对象(函数也是对象)是new Object的结果,所以对象可以作为实例对象,其构造函数是Object(),原型对象是Object.prototype

  【3】Object.prototype的原型对象是null

相关内容推荐

mns 配件常州汽车配件城本田五羊配件官网无锡乳化泵配件等离子电视配件重坦装什么配件大阳摩托150配件丽行配件配件不匹配110发动机配件iphone 可能不支持此配件汽车零配件售后西安宝马配件电话华菱驾驶室配件哈尔滨 丰田配件柏翠 面包机配件兰德酷路泽配件进相机配件电动工具配件公司减速机齿轮配件招聘汽车配件采购南京卖汽车配件电脑配件价格标签昕锐 配件狙击手3配件奥普浴霸 配件欧米茄表把配件柴油三轮车配件广州坤江汽车配件电脑配件的货源4S没有配件上海华特汽车配件苏州金德精密配件玛蒂尔达 配件长春比亚迪配件汽车配件一批加拿大的配件电脑主机的配件手机配件 日本汽车都有什么配件霸龙重卡驾驶配件菊花配件摩托车配件品牌水仙洗衣机配件坦克世界 e100配件伊苏8全配件小型粉碎机配件长城哈弗配件价格183的配件沃尔沃 配件 价格雅马哈50配件东风紫罗兰配件东风370配件隆尧汽车配件厂沈阳东风货车配件无锡光洋汽车配件重庆庆铃汽车配件赛车物语 配件4s店换配件吗奔驰4S店配件龙笔记本配件sta 2配件此ipad不支持此配件设备配件清单爱回收 配件心艺电动车配件电动车配件收纳捷达柴油的配件惠普打印机配件诸暨水暖配件厂4s店配件外卖吗长城赛弗的配件-8用什么配件大学生笔记本配件女生笔记本配件购汽车配件合同三星note3配件济南市配件城东风皮卡配件大全丰田配件供应商261 配件石家庄东风配件雪铁龙塞纳配件松吉配件在香港买电脑配件反应釜 配件配件三无产品汽车配件图片图标软件洗地机 配件本田五羊配件官网本田配件收纳开边机配件常州电动车配件西安汽车配件有限公司配件工作职责本田摩托车125配件北京笔记本配件otg配件冠道 配件卡罗拉08配件汽车配件锻造加工原装小松挖掘机配件扫地机器人 配件华星配件汽车配件价格图片电容器配件手机配件上市公司s8 配件真假美人相机配件深圳笔记本配件玉环县汽车配件有限公司小米3的配件宝马 在线配件高赛摩托车配件博世电钻 配件百电宝照明配件东莞批发净水器配件耙斗装岩机的配件汽车更换配件保修墙面打磨机的配件交换机 配件kindle 配件燃油助力车配件灯箱铝材 配件布自行车配件车把清障车的配件电脑配件 科目数控机床 配件给水配件名称快乐王子奥拓配件苹果7配件有什么附近的制冷配件福特配件电话号码九鼎汽车配件汽车配件 oem石家庄奥迪配件比亚迪f6配件螺杆泵的配件精益管配件价格江阴汽车配件有限公司名古屋 汽车配件diy发饰配件批发建设摩托车配件110富士相机配件收纳macbook pro配件汽车配件的税率长安之星2代配件桑塔纳配件价格杭州轴承配件老红岩金刚配件南宁 手机配件改装配件哪里买制冷设备配件生产汽车拉杆配件常州自行车配件上海飞众汽车配件三星配件价格表压线配件青岛汽车配件加工淘宝卖的汽车配件附近的挖机配件反曲 配件增城汽车配件厂铝合金型材配件三星i9300 配件深圳手机配件市场慈溪市汽车配件东风日产配件电话汽车配件员工资三菱柴油发电机配件超人剃须刀 配件常州电器配件单反需要的配件杭州 制冷配件临朐铝合金配件前锋燃气热水器配件三角电饭锅配件北汽幻速s2的配件昆明沃尔沃配件天天飞车配件升级电脑配件及耗材锤子pro配件守望者数码配件电线杆配件超越c300配件pvc下水管配件天启的狂怒配件温岭市机械配件厂门禁 配件比亚迪发动机配件美版iphone配件广汽欧蓝德配件坦克-7配件2015电脑配件安装电热水器需要配件南海汽车配件厂变速箱有什么配件iphone新奇配件门窗配件 招聘数码相机数码配件

合作伙伴

零配件导航

dh.jsfengchao.com
www.andmedia.cn
www.clhczx.cn
www.gzlyapi.com
www.28j.com.cn
www.xm5656.cn
baidu.07yue.com
www.bjdongwei.cn
www.28j.com.cn
top1.urkeji.com
www.china185.com
seo.china185.com
www.xm5656.cn
www.mtcddc.cn
www.andmedia.cn
www.akz.net.cn
www.desai360.com
www.maijichuang.cn
www.conductive-powder.com
niu.seo5951.com