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__ 的问题了,如果有疑惑的话,可以阅读 @nightire 凡哥的博文《理解 JavaScript(四)》。

参考:

http://segmentfault.com/blog/stephenlee/1190000000478987

http://bonsaiden.github.io/JavaScript-Garden/#object.prototype

延伸阅读:

细说JavaScript对象(1):对象的使用和属性

细说JavaScript对象(2):原型对象

细说JavaScript对象(3):hasOwnProperty

细说JavaScript对象(4): for in 循环

细说JavaScript对象(2):原型对象相关推荐

  1. 【Javascript】通过实例对象修改原型对象属性的值

    结论: 当原型对象的属性值为基本数据类型时,无法通过实例对象直接修改原型对象的属性值.当原型对象的属性值为引用数据类型时,可以直接通过实例对象修改原型对象的属性值. 基本类型的数据值有7种:字符串(S ...

  2. 面向过程和面向对象的编程思想 复习原型 构造函数和实例对象和原型对象之间的关系

    体会面向过程和面向对象的编程思想 <!DOCTYPE html> <html lang="en"> <head><meta charset ...

  3. ES6-改变对象的原型对象

    ES6-改变对象的原型对象 let person = {getGreeting () {return 'Hello';}};let dog = {getGreeting () {return 'woo ...

  4. 面向对象2(构造函数、实例对象、原型对象——关系理解)

    参考解释: 对象原型 构造函数与实例对象 构造函数与实例对象 关系: 实例对象是通过构造函数来创建的,创建的过程叫实例化. 示例代码: //1.自定义构造函数 function Person(name ...

  5. 深入javascript——构造函数和原型对象

    常用的几种对象创建模式 使用new关键字创建 最基础的对象创建方式,无非就是和其他多数语言一样说的一样:没对象,你new一个呀! var gf = new Object(); gf.name = &q ...

  6. [转]JavaScript构造函数及原型对象

    JavaScript中没有类的概念,所以其在对象创建方面与面向对象语言有所不同. JS中对象可以定义为"无序属性的集合".其属性可以包含基本值,对象以及函数.对象实质上就是一组没有 ...

  7. 【JavaScript高级教程】JavaScript prototype(原型对象)

    所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法. function Person(first, last, age, eyecolor) {this.fi ...

  8. 【javascript】对原型对象、原型链的理解

    原型对象,原型链这些知识属于基础类知识.但是平时开发过程中也很少用到. 看网上的意思,原型链用于es5开发场景下的继承.es6有了类语法糖之后,就自带继承了. 通过理解,个人画了一张原型链解构的关系图 ...

  9. javascript面向对象系列第一篇——构造函数和原型对象

    前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如何用构造函数和原型对象来创建对象 构造函数 构造函数是 ...

  10. JavaScript学习(四十八)—原型对象的增删改查

    JavaScript学习(四十八)-原型对象的增删改查 一.构造方法与原型对象的图解 二.型对象的增删改查 (一).什么是原型 每个函数都会有一个属性--prototype属性,这个属性都会有一个对象 ...

最新文章

  1. python中如何跳出多层循环
  2. pytorch笔记:torch.nn.MaxPool2d
  3. python线程池超过最大数量_python自定义线程池控制线程数量
  4. ios 侧滑返回停顿_iOS push侧滑返回功能实现方法
  5. a - 数据结构实验之串一:kmp简单应用_中高级面试必备:快速入门数据结构和算法
  6. 实现TcpIp简单传送
  7. 十一. Python基础(11)—补充: 作用域 装饰器
  8. javascript、jquery获取网页的高度和宽度
  9. dataframe基本函数
  10. spring注解 annotation
  11. asp.net 写入excel时,不能更新。数据库或对象为只读。
  12. 测试 SEP 14 MP1 新功能 Duplicate Hardware ID 自动修复
  13. geek_2013年How-To Geek的节日礼物指南:一定要装满东西
  14. C语言输入三角形三条边边长 算三角形面积
  15. 杨思卓:黑钻VS蓝石(2)
  16. python线性回归预测pm2.5_基于随机森林算法的PM2.5预测
  17. c语言编程麦粒问题,c语言编程常见问题解析(资源泄漏)
  18. Front Immunol 复现 | 4. 使用estimate包评估肿瘤纯度
  19. Arduino空气污染温湿度MQ135烟雾检测报警ESP8266 手机App socket
  20. 指针笔试题详细介绍,让你不再惧怕指针【c语言】

热门文章

  1. ipv6 neutron应用(一)
  2. Magento2创建自定义Widget 并通过添加图片选择器插入图片
  3. [RocketMQ]消息中间件—RocketMQ消息消费(一)
  4. iOS10推送适配完整说明
  5. TabIndex 属性 Tabindex=-1 与Tabindex=0、任意数字 (收录)
  6. 《Ruby程序员修炼之道》(第2版)—第1章1.1节进入Ruby的世界
  7. 【工具】 原版完美激活 Flash builder 4.7 【非破解激活】
  8. A.1.3-控制台输入,类型转换(int.Parse()),格式化输出
  9. win7 启用网络发现
  10. 准备在北京Tech·Ed上组织博客园聚会