【JS】对于__proto__、protoType、constructor的理解

这三个属性在js底层中经常用到,经常不知道其甚至,甚至老是把前两张搞混淆。今天主要记录下这三者的作用和用法。

在开始之前,我们先约定一些名词,如下:

【函数】,即我们通常用Function 或者Class 定义的

【对象】 即Function或Class的实例,

 特例,其实不管是Function还是 Class 其实都是特殊的Object,即 也是对象。

下面进入主题,我们调整下顺序“”先介绍 constructor:

 【constructor】从字面意思理解,constructor 为建造者、创造者。js的constructor也是这个意思,即对象的constructor属性指向该对象的建造者.

 由上可知:对象s 是由Son创建而来的,而Son则是由Function创建而来的。

 另外,有字面constructor的字面意思,可以知道constructor一般指向js的基础数据类型+Function,即:Number、String、Boolean、undefined、object、Null 但其中NUll 和undefined 是数据类型未止,所以是没有创造者的 ,其产生的对象也就没有constructor属性。

所以:constructor要么指向如上几种数据类型,要么指向Function(含Function的实现,如各种自定义类,以及Date ,Array 因为 Date、Array的constructor执向Function)   

 【prototype】 是函数特有的属性,表示:函数的原型对象,官方解释是:所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法。这句话咋一看很难理解。我们换一种方式就好理解了:

  1、所有函数声明后,都会自动隐形声明一个属性  prototype。默认的prototype指向一个对象,这个对象我们称之为“原型对象”,函数默认原型对象的构造器属性执向这个函数本身。

 这个原型有什么用呢?说到这里相信大家都有听过这个名词吧“原型链”,不错由于每个函数都有prototype属性,有继承关系的父子类,或者多层继承关系的类之间通过prototype形成了原型链。

这样做的作用是什么呢?当我们去访问一个对象的某个方法或者属性的时候,js最先会在构建这个对象的 函数(类)上查找是否含有该属性(或方法),如果则找到则返回并预备使用;如果没有,则回去这个函数的原型对象上去查找,如果则找到则返回并预备使用,如果没有找打则继续向上层原型对象找查找,知道原型对象放回Function为止。此时如果还没找到则返回 undefined(如果查找的方法,由于我们一般是这样写的:obj.xxx() 这样写表示查找并执行方法,如果没有xxx方法 执行的时候 就会报错)

所以,对象的属性、方法,来自构造其函数的定义和此函数的原型以及原型链。

举例一:对象的属性、方法,可以来之其构造的函数

            

这里对象f的属性"Test",来自构造f对象的函数F。                      我们想所有F构建出来的对象多一个Addr属性,通常我们可以修改F函数的定义

 

举例二:对象的属性方法,可以来自构造其函数的原型

举例三:对象的属性和方法,可以来自构造其函数的原型链

   题外话,ES6中class定义的方法,就是往其prototype中添加方法实现的。

最后一个是【__proto__】,__proto__最好理解:所有对象都会自动创建一个属性__proto__,这个属性指向构建这个对象的函数的原型。

p.__proto__==p.constructor.prototype

所以往对象的__proto__添加属性和方法,添加后再从构造这个对象的函数创建的对象就具备这些新的属性和方法了(等价于直接往函数的原型中添加方法和属性)

此文结束,这下你对constructor,prototype、__proto__认识清晰了吗? 那试试下面几道测试题,试试现在你的理解是否正确?

function Say(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Say('jone', 30);
console.log(person instanceof Say);                                        
console.log(person.__proto__ === Say.prototype);                            
console.log(person.__proto__.constructor === Say.prototype.constructor);    
var obj = {};
console.log(obj.__proto__ == Object.prototype)                             
var fn = function() {};
console.log(fn.__proto__ === Function.prototype);
原文地址:https://www.cnblogs.com/paulxie/p/13809296.html