JS中的原型链

原创 2015年11月18日 22:10:21

关于__proto__和prototype的一些理解

http://www.cnblogs.com/zzcflying/archive/2012/07/20/2601112.html


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

new操作符的操作是
1.var p = {}
2.p.__proto__ =  Person.prototype
3.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上的图:
__proto__ <wbr>与prototype的区别,js函数声明与创建




版权声明:本文为博主原创文章,未经博主允许不得转载。

彻底理解javascript中的原型链

要弄清楚原型链就要先弄清楚 function 类型,在javascript中没有类的概念,都是函数,所以它是一门函数式的编程语言。类有一个很重要的特性,就是它可以根据它的构造函数来创建以它为模板的对象...
  • ljl157011
  • ljl157011
  • 2014年02月22日 13:38
  • 12502

浅析JavaScript原型链与原型链式继承

原型链与原型链式继承上篇总结了下JavaScript的作用域链的问题,欢迎拍砖!浅析JavaScript作用域链继上篇总结中提出的情况 同样都是链,但这两个链往上追朔的顶点是不一样的;并且为了增强...
  • SirM2z
  • SirM2z
  • 2016年01月10日 20:44
  • 1097

javascript中的对象详解,以及对象和原型链

除了5种基本类型外,JS中剩下的就是对象 (1)对象的定义:直接定义:var test={x:1,y:1}new方式创建:var test=new Object({x:1})Object.create...
  • liwusen
  • liwusen
  • 2016年06月11日 21:13
  • 1212

深入理解JS继承和原型链

对于那些熟悉基于类的面向对象语言(Java 或者 C++)的开发者来说,JavaScript 的语法是比较怪异的,这是由于 JavaScript 是一门动态语言,而且它没有类的概念( ES6 新增了...
  • zls986992484
  • zls986992484
  • 2016年12月17日 11:18
  • 3007

在原型链之中的查询及this指向问题

/** * Created by zhang on 2017/5/9. */var Sup = function(){ this.name = "sup"; this.getNam...
  • u012182627
  • u012182627
  • 2017年05月09日 21:44
  • 202

JS重点整理之JS原型链彻底搞清楚

彻底搞清楚原型链。看图理解原型链。从对象、原型对象、原型链进行一步步分析,每一块都有根据自己的理解画图,更容易理解,又有例子代码佐证。 最普通的对象:有__proto__属性(指向其原型链...
  • sinat_21274091
  • sinat_21274091
  • 2016年10月06日 01:58
  • 9187

JS高级---原型链(一看就懂,但18岁以下请绕道)

1)小明是小明妈生的,小狗是小狗妈生的。小明和小狗都是对象实例,而小明妈和小狗妈就是原型。原型也是对象,叫原型对象。      2)小明妈和小明爸啪啪啪能生出一堆小明明、小狗妈和小狗爸啪啪啪能生出一...
  • xiaotao_css
  • xiaotao_css
  • 2017年05月27日 16:14
  • 1513

JavaScript概念总结:作用域、闭包、对象与原型链

1 JavaScript变量作用域 1.1 函数作用域 没有块作用域:即作用域不是以{}包围的,其作用域完成由函数来决定,因而if /for等语句中的花括号不是独立的作用域。 如前述,JS的在函...
  • zzulp
  • zzulp
  • 2012年11月03日 20:49
  • 17701

【JavaScript】5.面试题一原型和原型链

一、题目 1、如何准确判断一个变量是数组类型? var array=[]; console.log(array instanceof Array);//true 判断引用类型的具体...
  • benben513624
  • benben513624
  • 2017年09月28日 07:03
  • 663

关于javascript原型链上的属性

//创建一个构造函数 function P() { this.name="lishi"; this.age=18; }//给P这个构造函数指定一个原型对...
  • jayhkw
  • jayhkw
  • 2016年12月14日 18:31
  • 1397
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JS中的原型链
举报原因:
原因补充:

(最多只允许输入30个字)