资讯专栏INFORMATION COLUMN

关于__proto__和prototype的一些理解

junfeng777 / 2646人阅读

摘要:也就是说构造,也可以称之为初始化。关键在于第二步,我们来证明一下这段代码会返回。按照标准,是不对外公开的,也就是说是个私有属性,但是的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。其余的也都是同样的道理。

下面的写法在javascript是很常见的,但是javascript中的new的执行过程是怎么样子的呢?看下面写法:

var Person = function(name) {
    this.name = name;
}
var p = new Person();

new操作符的操作是:

var p = {}
p.__proto__ = Person.prototype
Person.call(p)
var p={}; 也就是说,初始化一个对象p。
p.__proto__ = Person.prototype;
Person.call(p);也就是说构造p,也可以称之为初始化p。

关键在于第二步,我们来证明一下:

var Person = function() {}
var p = new Person();
alert(p.__proto__ ==  Person.prototype)

这段代码会返回true。说明我们步骤2的正确。

那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。

好,概念说清了,让我们看一下下面这些代码:

var Person = function () { };
Person.prototype.Say = function () {
    alert("Person say");
}
var p = new Person();
p.Say(); 

这段代码很简单,相信每个人都这样写过,那就让我们看下为什么p可以访问Person的Say。

首先var p=new Person();可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性,于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了Person.prototype.Say=function(){}; 于是,就找到了这个方法。

好,接下来,让我们看个更复杂的。

var Person = function () { };
Person.prototype.Say = function () {
    alert("Person say");
}
Person.prototype.Salary = 50000;
var Programmer = function () { };
Programmer.prototype = new Person();
Programmer.prototype.WriteCode = function () {
    alert("programmer writes code");
};
Programmer.prototype.Salary = 500;
var p = new Programmer();
p.Say();
p.WriteCode();
alert(p.Salary);  

我们来做这样的推导:

var p=new Programmer()可以得出p.__proto__=Programmer.prototype;

而在上面我们指定了Programmer.prototype=new Person();我们来这样拆分,var p1=new Person();Programmer.prototype=p1;那么:

p1.__proto__=Person.prototype;

Programmer.prototype.__proto__=Person.prototype;

由根据上面得到p.__proto__=Programmer.prototype。可以得到p.__proto__.__proto__=Person.prototype。

好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去p.__proto__,也就是Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去p.__proto__.__proto__,也就是Person.prototype中去找,于是就找到了alert(“Person say”)的方法。

其余的也都是同样的道理。

再来一张stackoverflow上的图:

可以把prototype可以当成是一个指针,当new一个方法的时候,指向的都是一个内存区域。
看完这些,感觉对原型链的了解应该差不多了吧。

转自与:http://www.cnblogs.com/zzcfly...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80176.html

相关文章

  • 关于javascript中原型原型链

    摘要:先来一个构造函数构造一个人类实例化一个对象看看的名字是什么打印结果先说一个前提只要是函数,就会有一个属性,可以理解为子代的原型遗传基因只要是对象,就会有一个方法,可以理解为向上寻找原型的方法。 关于javascript中的原型和原型链 我GitHub上的菜鸟仓库地址: 点击跳转查看其他相关文章 文章在我的博客上的地址: 点击跳转         关于javascript中的原型和原...

    SmallBoyO 评论0 收藏0
  • 原型链二:Function原型链问题

    摘要:每个函数都有一个属性构造函数指向实例原型如下图重点理解实例对象指向实例原型对象参考原博客的那个部分挖来下图理解之后我们来看在声明函数的时候有一种声明方法是构造函数下面参考阮一峰第三种声明函数的方式是构造函数。 理解关于Function的原型链问题 关于Function的原型链问题的一些个人粗略理解,欢迎指正错误的地方 可以看这篇文章:https://github.com/KieSun...

    dingda 评论0 收藏0
  • 关于javascript原型原型链,看我就够了(二)

    摘要:原文链接关于的原型和原型链,看我就够了一参考链接闯关记之原型及原型链之原型与原型链一篇文章带你理解原型和原型链彻底理解原型链一的默认指向图解和的三角关系原型和原型链三张图搞懂的原型对象与原型链 温故 创建对象的三种方式 通过对象直接量 通过new创建对象 通过Object.create() js中对象分为两种 函数对象 普通对象 仔细观察如下代码 function Foo(na...

    eccozhou 评论0 收藏0
  • 关于JS原型链理解

    摘要:的原型链,需要深刻的研究才能搞懂。对象都是通过函数即构造函数创建的。即这里的成为隐式原型。而构造函数的属性指向自身。这个对象的构造函数的是一个对象。走到原型链的终结。 - JS是一个非常有魅力的语言也是一个比较烦人的语言,主要就是因为他的特殊性灵活性。 JS的原型链,需要深刻的研究才能搞懂。不要纠结细节吧。实在不行就按这个死背住,慢慢就理解了。总之吧就是一句话万物皆对象。 结合这个图示...

    vvpvvp 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<