您的位置:首页 > Web前端 > JavaScript

简单理解javascript原型及原型链

2016-05-28 10:12 555 查看

简单理解javascript原型及原型链

原型和原型链式javascrpit中很重要的概念,但是无论书上还是网上 ,不少关于javascript原型和原型链的解释都不易理解,所以本人在此介绍一下自己的简单理解,希望对大家有帮助

原型

(阅读时,请务必注意类型,比如实例对象是对象,构造函数是函数,原型对象是对象)

首先,先做一些定义

var Person = function(){ var name="person_private_name";}

var man = new Person();

Console.log(man.name);   //undefined


在这里提出一个问题,man是Person是一个实例对象,那么man能不能获得Person的属性name呢?

答案是不能

那要怎么样才能使得man获得Person的属性和方法?

答案是通过Person的原型对象

那么,这段代码就应该改成

var Person = function(){ var name="person_private_name";}

Person.prototype.name="person_public_name";

var man = new Person();

Console.log(man.name);   //person_public_name


这个Person.prototype到底是怎么回事呢,我们通过图来说明

注意!!prototype是一个指针,指向Person的Person.prototype对象,现在把Person.prototype放在Person内,纯属方便理解!!!!下图绿色区域,是prototype指向的地方(Person.prototype)



我们把实例对象(man)需要访问的属性和方法放在绿色区域里面,这片绿色区域,就是Person的prototype(原型)。

当我们需要添加更多的可供实例对象(man)使用的属性和方法的时候,我们就可以这么做:

Person.prototype.age="person_public_age";
//向person原型添加属性而不是向person添加

Person.prototype.eat=function(){alert("person eating!!");}
//向person原型添加方法而不是向person添加


需要补充的是,每个原型对象(prototype)都拥有一个constructor指向本身,比如Person有Person.prototype,那么Person.prototype就有Person.prototype.constructor,而这个Person.prototype.constructor,就指向Person,用图来说明



当然,上图左右的两种理解方式都可以,简单来说就是Person的prototype指向Person.prototype(这不是废话么),然后Person.prototype.constructor指向Person(重点是这个)

现在,我们在看看书上的解析,应该好理解多了

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。 —– 《JavaScript高级程序设计》(第3版)147页

原型链

说原型链,必须要给上面的部分补充 _ proto _ 这个概念。

当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262第5版中管这个指针叫[[prototype]]。虽然在脚本中没有标准的方式访问[[prototype]],但Firefox、Safari、Chrome在每个对象上都支持一个属性_ proto _; ——《JavaScript高级程序设计》(第3版)148页

简单来说,就是实例对象(man)可以通过_ proto _找到构造函数(person)的原型对象(person.prototype)。

也就是找原型对象啦

也就是相当于找构造函数的那个共享区域啦 (注:这是我自己的理解)

”Firefox、Safari、Chrome在每个对象上都支持一个属性_ proto “ 这也是很重要的一句话,文章开头说务必注意类型,这里就用上了。我们说实例对象是对象,那么实例对象有 _proto _ 。但是原型对象呢?原型对象也是对象,所以原型对象也有_ proto _。所以本文第一张图补充完整是这样的



(注:网上有些解析Object的_proto_指向null)

就酱,一条很短的原型链就出来了,不难理解吧,有兴趣的看看书里的描述

假如我们让原型对象等于另一个类型的实例,结果会怎样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。 —– 《JavaScript高级程序设计》(第3版)162页

继承

继承是通过原型链来实现的,换个说法,继承是通过延长这条原型链实现的。

从本文第三张图做例子,我现在想在Person后面再加多个构造函数,命名为Person_Second,要怎么做呢?

看第三张图,图中Person到Object是Person.prototype连到Object.prototype上面去的,那么Person_Second.prototype也是要连到Person.prototype上面去的,在代码中是这么写

var Person=function(){}
Person.prototype.person_name="person_name";

var Person_Second=function(){}
Person_Second.prototype = new Person(); //继承了Person
Person_Second.prototype.person_second_name="person_second_name";

var women = new Person_Second();
console.log(women.person_name);  //person_name
console.log(women.person_second_name);  //person_second_name


看图:



以上

如有错误请指出

欢迎加QQ交流:285482599
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息