JavaScript中的__proto__和prototype的深度探究

注:本人在探究__proto__和prototype是我是通过火狐浏览器来就行验证。

在学习JavaScript的时候在控制台输出(即:console.log())某个类的时候我们会发现他有一个prototype属性,而这个属性内部有个许多的内容。我通过学习还得知存在着__proto__这个隐藏属性。接下来我就细细的谈论下我对__proto__和prototype的理解和看法。

图1

    如上图所示这是一个类空间的直观所示图通过下面代码我们很容易观察到:

function obj(){}
console.log("obj",obj);
console.log("obj.__proto__",obj.__proto__);

输出结果为:

图2
图3

通过上面的输出我们就可以发现每个类空间有这如图1那样的内部结构,并且prototype图1所示右半部分空间(即:原型空间)。通过继续打开constructor这个属性,我们发现他有指向obj()这个类本身。如下图结构。

图4

说了这么多的prototype那买我们接下来说一说__proto__这个属性,我们先来看下面代码以及输出:

function obj(){}
console.log("obj",obj);
console.log("obj.__proto__",obj.__proto__);
console.log("obj.prototype.__proto__",obj.prototype.__proto__);
console.log("Function",Function);
console.log("Object",Object);
console.log("obj.__proto__ === Function.prototype",obj.__proto__ === Function.prototype);
console.log("obj.prototype.__proto__ === Object.prototype",
                    obj.prototype.__proto__ === Object.prototype);
图5
图6
图7​​​

通过图5我们发现obj.__proto__ === Function.prototype和obj.prototype.__proto__ === Object.prototype的结果都是ture。这个输出充分的证明了obj的__proto__指向与Function的prototype指向完全相同(即:obj的__proto__指向Function的原型空间);obj原型空间中的__proto__的指向与Object的prototype的指向相同(即:obj原型空间中的__proto__的指向Object的原型空间)。

既然obj这个类与Function和Object都有关系,那么我们看看Function和Object空间和对应的原型空间都是怎么样的,通过多次试验证了最终结果,通过以下结果可以说明:

console.log("Function.prototype",Function.prototype);
console.log("Function.__proto__",Function.__proto__);
console.log("Function.prototype === Function.__proto__",
                    Function.prototype === Function.__proto__)

console.log("Function.prototype.__proto__",Function.prototype.__proto__);
console.log("Object.prototype",Object.prototype);
console.log("Function.prototype.__proto__ === Object.prototype",
                    Function.prototype.__proto__ === Object.prototype);

console.log("Function.prototype",Function.prototype);
console.log("Object.__proto__",Object.__proto__);
console.log("Function.prototype === Object.__proto__",
                    Function.prototype === Object.__proto__);

console.log("Object.prototype.__proto__",Object.prototype.__proto__);
图8​​​​​​
图9
图10
图11
图12

通过图9我们可以得到Function的__proto__和Function的prototype一样指向其原型空间。

通过图10我们可以得到Function原型空间中的__proto__指向Object的原型空间。

通过图11我们可以得到Object的__proto__指向Function的原型空间。

通过图12我们可以得到Object原型空间中的__proto__指向null(即:不指向)。

接下来我们通过通过几个代码说明类的原型空间和对象的__proto__的关系

function obj(){}
var num1 = new obj();
var num2 = new obj();

console.log("num1.prototype",num1.prototype);
console.log("obj.prototype",obj.prototype);
console.log("num1.__proto__",num1.__proto__);
console.log("num2.__proto__",num2.__proto__);
console.log("obj.prototype === num1.__proto__",obj.prototype === num1.__proto__);
console.log("obj.prototype === num2.__proto__",obj.prototype === num2.__proto__);
num1.__proto__.mumber1 = 100;
console.log("num1.__proto__",num1.__proto__);
console.log("num2.__proto__",num2.__proto__);
num2.__proto__.mumber1 = 200;
console.log("num1.__proto__",num1.__proto__);
console.log("num2.__proto__",num2.__proto__);
图13

通过图13我们可以发现对象没有prototype属性,有__proto__属性,并且不管是num1还是num2的__proto__都指向他们所属类的原型空间。发现在原型空间中设置一个新变量,通过num1.__proto__.mumber1 = 100; 创建后num2.__proto__也有了这个变量。通过num2.__proto__.mumber1 = 200;改变后num1.__proto__.mumber1的值也同时改变了,所以说明__proto__所指向的空间的单一的,这个空间就是这个对象所属类的原型空间。

下面通过一张同对上述的所有内容进行一下形象的总结:

注:  在以前的火狐浏览器中是显示__proto__这个显示属性(同时它还是个指针)。但由于这是个隐形属性,现在已经不显示了。但在后面我发现不管那几个类、对象、函数都有<prototype>这个灰色的属性(同时它还是个指针)。而通过点开<prototype>属性以及通过console.log(XXX._proto__)就可以发现这两个指向的内容是一样的(这里内容仅供参考并没有证明)。

    

猜你喜欢

转载自blog.csdn.net/lixiaotianx/article/details/83213129
今日推荐