资讯专栏INFORMATION COLUMN

js 原型链

wua_wua2012 / 2075人阅读

摘要:当通过原型链继承了之后,就变成了的一个实例,因此它也拥有了一个它自己的属性就跟专门创建了一个属性一样。有鉴于此,再加上前面刚刚讨论过的由于原型中包含引用类型值所带来的问题,实践中很少会多带带使用原型链

记录下自己对js 原型的一些理解
先看一下什么是 ····原型链

function Foo(){}
Foo.prototype.num = 3;
// new Foo( ) 将返回一个对象 把这个对象赋值给了 bar 
var bar = new Foo();
// bar 是怎么找到的原型下面的num呢?
alert(bar.num); //3  

bar并没有num 属性,它是怎么拿到3的呢 此处的 bar 就是通过原型链找到了值
原型链
JavaScript中的对象有一个特殊的 __proto__ 内置属性,其实就是对于其他对象的引用(关联)。当我们使用 function关键字声明一个函数时,系统会自动创建一个对象,访问这个对象可以通过 函数名.prototype 访问(我们一般把这个对象叫做原型对象),当使用 new 关键字调用函数(这时我们一般把这个函数称为构造函数)时其中有一个步骤就是对创建的对象进行原型关联,关联到声明函数时创建的那个对象(函数名.prototype指向的那个对象)

上面例子 中使用 new 关键字调用 Foo()函数时会创建一个对象我们把这个对象赋值给了 bar ; bar对象内部的.__proto__属性会关联到声明函数时创建的那个对象(Foo.prototype) , bar.num属性在bar中无法找到时,就会访问bar.__proto__查找,这个过程会持续到找到匹配的属性名或者查找完整条prototype链(所有普通的[[Prototype]]链最终都会指向内置的Object.prototype)
,因此上面例子的原型链是这样的

bar.__proto__ -- 指向 --> Foo.prototype --然后(Foo.prototype.__proto__) -- 指向 --> Object.prototype

因此
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念
对prototype更详细的介绍请看这里(https://developer.mozilla.org...

原型链的问题

包含引用类型值的原型属性会被所有实例共享;(而这也正是为什么要在构造函数中,而不是在原型对象中定义属性的原因)在通过原型来实现继承时,原型实际上会变成另一个类型的实例。于是,原先的实例属性也就顺理成章地变成了现在的原型属性了。下列代码可以用来说明这个问题。

function SuperType(){   
  this.colors = ["red", "blue", "green"];
}
function SubType(){}//继承了SuperType
SubType.prototype = new SuperType();
var instance1 =newSubType();
instance1.colors.push("black");
//"red,blue,green,black"
alert(instance1.colors);
var instance2 = new SubType();
//"red,blue,green,black"
alert(instance2.colors);

SuperType构造函数定义了一个colors属性,该属性包含一个数组(引用类型值)。SuperType的每个实例都会有各自包含自己数组的colors属性。当SubType通过原型链继承了SuperType之后,SubType.prototype就变成了SuperType的一个实例,因此它也拥有了一个它自己的colors属性——就跟专门创建了一个SubType.prototype.colors属性一样。但结果是什么呢?结果是SubType的所有实例都会共享这一个colors属性。而我们对instance1.colors的修改能够通过instance2.colors反映出来,就已经充分证实了这一点。

在创建子类型的实例时,不能向超类型的构造函数中传递参数。实际上,应该说是没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。有鉴于此,再加上前面刚刚讨论过的由于原型中包含引用类型值所带来的问题,实践中很少会多带带使用原型链

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

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

相关文章

  • JS基础-原型原型真的不能一知半解

    摘要:原型链和对象的原型是对象实例和它的构造函数之间建立的链接,它的值是构造函数的。对象的原型根据上文提到的构造调用函数的时候会创建一个新对象,自动将的原型指向构造函数的对象。 showImg(https://segmentfault.com/img/remote/1460000020185197); JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清...

    changfeng1050 评论0 收藏0
  • 从实现角度分析js原型

    摘要:从实现角度分析原型链欢迎来我的博客阅读从实现角度分析原型链网上介绍原型链的优质文章已经有很多了,比如说作为补充,就让我们换个角度,从实现来分析一下吧本文假设你对原型链已经有所了解。 从实现角度分析js原型链 欢迎来我的博客阅读:《从实现角度分析js原型链》 网上介绍原型链的优质文章已经有很多了,比如说: https://github.com/mqyqingfeng/Blog/issu...

    CompileYouth 评论0 收藏0
  • 理解js原型与继承

    摘要:相当于在用原型继承编写复杂代码前理解原型继承模型十分重要。同时,还要清楚代码中原型链的长度,并在必要时结束原型链,以避免可能存在的性能问题。 js是一门动态语言,js没有类的概念,ES6 新增了class 关键字,但只是语法糖,JavaScript 仍旧是基于原型。 至于继承,js的继承与java这种传统的继承不一样.js是基于原型链的继承. 在javascript里面,每个对象都有一...

    wthee 评论0 收藏0
  • js原型 原型 原型的继承

    摘要:图片描述缺点是无法实现多继承可以在构造函数中,为实例添加实例属性。 对象的方法 Object.assign() 对象可以简写 ,如果 key 和 value 相等则可以简写 let name = xm; let age = 2; let obj = { name, age, fn(){ // 可以省略函数关键字和冒号: console.log(2...

    soasme 评论0 收藏0
  • js原型

    摘要:构造函数,实例,原型三者的关系如下图构造函数是构成整个原型链的关键,是他利用将原型传给了后代。因此,通过操纵构造函数的,就能够操纵原型链,从而对原型链进行自在的拼接。 要理解js的原型链主要就是理清楚以下三者的关系: 构造函数的protitype属性 对象的__proto__属性 对象的constructor属性 在js中,函数作为一等公民,它是一个对象,可以拥有自己的属性,可...

    NervosNetwork 评论0 收藏0
  • 【前端基础进阶】JS原型原型、对象详解

    摘要:二构造函数我们先复习一下构造函数的知识上面的例子中和都是的实例。这两个实例都有一个构造函数属性,该属性是一个指针指向。原型链其中是对象的实例。 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。下面举例说明 var o1 = {}; var o2 =new Objec...

    explorer_ddf 评论0 收藏0

发表评论

0条评论

wua_wua2012

|高级讲师

TA的文章

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