ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JS对象进阶-理解prototype、proto、constructor

2021-09-29 11:32:54  阅读:161  来源: 互联网

标签:Function Object 进阶 People proto JS constructor prototype true


JS中最复杂的莫过于prototype、proto和constructor之间的三角关系,搞清楚它们之间的关系对理解JS这门语言很重要,下面是我画的一张关系图,本文以该图为例解释它们之间的关系。

基本概念

function People(){};
var p1 = new People;
var o1 = new Object;
var f1 = new Function;

【构造函数】用来初始化实例对象的函数是构造函数。图中浅绿色的People()、Object()、Function()函数是构造函数。

【实例对象】通过构造函数的new操作符创建的对象是实例对象。图中橘黄色的p1、o1和f1都是实例对象。

【prototype】prototype是构造函数的属性,指向实例的原型对象。同一个构造函数的实例对象拥有相同的原型对象,所以可以使用原型对象实现继承。

function People(){};
var p1 = new People;
var o1 = new Object;
var f1 = new Function;

People.prototype === p1.__proto__; // true
Object.prototype === o1.__proto__; // true
Function.prototype === f1.__proto__; // true

【constructor】constructor是原型对象的属性,指向对应的构造函数。

function People(){};
People.prototype.constructor === People; // true

Object.prototype.constructor === Object; // true
Function.prototype.constructor === Function; // true

由于实例对象可以继承原型对象的属性和方法,所以实例对象也有constructor属性,指向对应的构造函数。

function People(){};
var p1 = new People;
p1.constructor === People; // true

var f1 = new Function;
f1.constructor === Function; // true

var o1 = new Object;
o1.constructor === Object; // true

【proto】 proto是实例对象的属性,指向对应的原型对象。

function People(){};
var p1 = new People;
var f1 = new Function;
var o1 = new Object;

p1.__proto__ === People.prototype; // true
f1.__proto__ === Function.prototype; // true
o1.__proto__ === Object.prototype; // true

详细说明

第一部分

People.prototype不仅是实例对象的原型对象,它自身也是一个实例对象,这也是为什么它有proto属性的原因。既然是实例对象肯定有对应的构造函数和原型对象:它的原型对象是Object.prototype;它的构造函数是People()。

function People(){};

var p1 = new People;
People.prototype.__proto__ === Object.prototype; // true

People.prototype作为原型对象时,自身拥有constructor属性,所以它会覆盖继承自原型对象Object.prototype的constructor属性。

function People(){};

var p1 = new People;
People.prototype.hasOwnProperty('constructor'); // true
People.prototype.constructor === People; // true

Function.prototype和上面类似,当Function.prototype作为实例对象时它的原型对象也是Object.prototype;构造函数是Function()。

Function.prototype.__proto__=== Object.prototype // true
Function.prototype.constructor === Function // true

Object.prototype也和上面类似,不仅是实例对象的原型对象,它自身也是一个实例对象。那么Object.prototype作为实例对象时,它的原型对象和构造函数是什么呢?答案:原型对象是null,构造函数是Object()。或许这也是为什么typeof null === 'object'

// Object.prototype作为实例对象
Object.prototype.__proto__ === null; // true

// Object.prototype作为原型对象
Object.prototype.constructor === Object; // true

第二部分

在JavaScript中,函数是Function类型的实例,所以函数也是对象。如果把函数People、函数Function和函数Object都看做实例,它们的构造函数都是Function(),它们的原型对象都是Function.prototype。

function People(){};
People.__proto__ === Function.prototype;// true
Object.__proto__ === Function.prototype;// true
Function.__proto__ === Function.prototype;// true

实例对象People、Function和Object本身没有constructor属性,它们继承了原型对象Function.prototype的constructor属性。

function People(){};
People.constructor === Function;// true
Object.constructor === Function;// true
Function.constructor === Function;// true

Function.hasOwnProperty('constructor') // false
Object.hasOwnProperty('constructor') // false
People.hasOwnProperty('constructor') // false

所有函数都可以看做是构造函数Function()的new操作的实例化对象,所以它们的原型对象都是Function.prototype。

Function.__proto__ === Function.prototype;// true
Object.__proto__ === Function.prototype;// true
People.__proto__ === Function.prototype;// true

总结

如果要解释原型、原型链和继承,一定要画图

// 原型和原型链
var People = function () {};

var p1 = new People(); // {__proto__: {}}

console.log(p1.__proto__ === People.prototype)

console.log(People.prototype.__proto__ === Object.prototype)

console.log(Object.prototype.__proto__ === null)


// 继承:p1 先去构造函数People上找toString,找不到会沿着原型链去Object上找,这就是继承
console.log(p1.toString); //  ƒ toString() { [native code] }

使用new调用函数的时候,主要做了三个工作:创建实例对象、调用内部的constructor函数初始化this绑定、实例原型绑定

标签:Function,Object,进阶,People,proto,JS,constructor,prototype,true
来源: https://www.cnblogs.com/yesyes/p/15352073.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有