Javascript 学习笔记之 对象篇(二) : 原型对象

 更新时间:2014年06月24日 08:57:13   投稿:hebedich  
Javascript 并没有类继承模型,而是使用原型对象 prototype 进行原型式继承。尽管人们经常将此看做是 Javascript 的一个缺点,然而事实上,原型式继承比传统的类继承模型要更加强大。举个例子,在原型式继承顶端构建一个类模型很简单,然而反过来则是个困难得多的任务。

Javascript 是唯一一个被广泛运用的原型式继承的语言,所以理解两种继承方式的差异是需要时间的。

第一个主要差异就是 Javascript 使用原型链来继承:

function Foo() {
 this.value = 42;
}
Foo.prototype = {
 method: function() {}
};
function Bar() {}

设置 Bar 的 prototype 为 Foo 的对象实例:

Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';

确保 Bar 的构造函数为本身,并新建一个 Bar 对象实例:

Bar.prototype.constructor = Bar;
var test = new Bar();

下面我们来看下整个原型链的组成:

test [instance of Bar]
 Bar.prototype [instance of Foo]
 { foo: 'Hello World' }
 Foo.prototype
  { method: ... }
  Object.prototype
  { toString: ... /* etc. */ }

在上面的例子中,对象 test 将会同时继承 Bar.prototype 和 Foo.prototype。因此它可以访问定义在 Foo 中的函数 method。当然,它也可以访问属性 value。需要提到的是,当 new Bar() 时并不会创建一个新的 Foo 实例,而是重用它原型对象自带的 Foo 实例。同样,所有的 Bar 实例都共享同一个 value 属性。我们举例说明:

test1 = new Bar();
 test2 = new Bar();
 Bar.prototype.value = 41;
 test1.value //41
 test2.value//41

原型链查找机制

当访问一个对象的属性时,Javascript 会从对象本身开始往上遍历整个原型链,直到找到对应属性为止。如果此时到达了原型链的顶部,也就是上例中的 Object.prototype,仍然未发现需要查找的属性,那么 Javascript 就会返回 undefined 值。

原型对象的属性

尽管原型对象的属性被 Javascript 用来构建原型链,我们仍然可以值赋给它。但是原始值复制给 prototype 是无效的,如:

function Foo() {}
Foo.prototype = 1; // no effect

这里讲个本篇的题外话,介绍下什么是原始值:
在 Javascript 中,变量可以存放两种类型的值,分别是原始值和引用值。

1.原始值(primitive value):

原始值是固定而简单的值,是存放在栈 stack 中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
原始类型有以下五种型: Undefined, Null, Boolean, Number, String。

2.引用值(reference value):

引用值则是比较大的对象,存放在堆 heap 中的对象,也就是说,存储在变量处的值是一个指针  pointer,指向存储对象的内存处。所有引用类型都集成自 Object。
原型链性能问题

如果需要查找的属性位于原型链的上端,那么查找过程对于性能而言无疑会带来负面影响。当在性能要求必要严格的场景中这将是需要重点考虑得因素。此外,试图查找一个不存在属性时将会遍历整个原型链。
同样,当遍历一个对象的属性时,所有在原型链上的属性都将被访问。

总结

理解原型式继承是写较为复杂的 Javascript 代码的前提,同时要注意代码中原型链的高度。当面临性能瓶颈时要学会将原型链拆分开来。此外,要将原型对象 prototype 和原型 __proto__ 区分开来,这里主要讨论原型对象 prototype 就不阐述关于原型 __proto__ 的问题了,

相关文章

  • 全面理解JavaScript中的闭包

    全面理解JavaScript中的闭包

    将外部作用域中的局部变量封闭起来的函数对象称为闭包(Closure),被封闭起来的变量与封闭它的函数对象有相同的生命周期,这在JavaScript中比较难理解而且十分重要,接下来带大家一起来全面理解JavaScript中的闭包:
    2016-05-05
  • ParseInt函数参数设置介绍

    ParseInt函数参数设置介绍

    经常用ParseInt函数转换字符串为int数值,ParseInt函数有两个参数可以设置,其中第二个参数可以缺省
    2014-01-01
  • 辨析JavaScript中的Undefined类型与null类型

    辨析JavaScript中的Undefined类型与null类型

    Undefined与null都是js中的基本数据类型,然而正如它们的名字那样,未初始化和空并不相同,下面我们就来详细辨析JavaScript中的Undefined类型与null类型:
    2016-05-05
  • 贴一个在Mozilla中常用的Javascript代码

    贴一个在Mozilla中常用的Javascript代码

    贴一个在Mozilla中常用的Javascript代码...
    2007-01-01
  • 了解ESlint和其相关操作小结

    了解ESlint和其相关操作小结

    这篇文章主要介绍了了解ESlint和其相关操作小结,详细的介绍了什么是ESlint以及ESlint规范,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Javascript中Date类型和Math类型详解

    Javascript中Date类型和Math类型详解

    这篇文章主要给大家介绍了Javascript中Date类型和Math类型的一些基础知识,非常的实用,有需要的小伙伴可以参考下
    2016-02-02
  • 最实用的JS数组函数整理

    最实用的JS数组函数整理

    本篇文章小编给大家整理了非常全的JS数组函数以及相关的写法规则,希望能够对读者们起到帮助和参考。
    2017-12-12
  • js转义字符介绍

    js转义字符介绍

    有时候js得到json串中含有"<"和">" ,那么两个尖括号中间的文字是无法在html页面显示出来的,必须用转义字符
    2013-11-11
  • javascript列表框操作函数集合汇总

    javascript列表框操作函数集合汇总

    这篇文章主要是对javascript列表框操作函数进行了详细的汇总介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-11-11
  • 详解JavaScript中数组和字符串的lastIndexOf()方法使用

    详解JavaScript中数组和字符串的lastIndexOf()方法使用

    这篇文章主要介绍了详解JavaScript中数组和字符串的lastIndexOf()方法使用,文中特别提及了IE8的兼容问题以及for in的使用问题,需要的朋友可以参考下
    2016-03-03

最新评论