两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客:

理解JavaScript中原型继承

JavaScript中的原型继承

这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误理解。今天看《Understanding Scopes》这让我从新思考了一下原型继承,更重要的是站在一个继承设计者的角度再看一下原型继承。

在传统的面向类的继承体系中,我们有个Best Practices是优先使用(对象)组合代替(类)继承,而原型继承是这个思想的一个运用。和面向对象和函数式编程一样,使用几乎任何语言都可以实现这样的思想,我以前学的只是这个思想的一个JavaScript实现,而已。

基于原型的继承其实是一种组合式的继承,朴素的说法就是子域中属性找不到的话就去父域中找找,这里的父域是用原型(__proto__)去引用的,依次递归整个原型链。最终的实现其实就是对象的组合。子对象包含父对象的引用。既然是继承必然涉及到重名问题,子对象和父对象各自相当于一个作用域,重名问题的处理也是就近(可覆盖shadow/隐藏hide)原则,即子作用域的同名属性会起作用,隐藏了父作用域的同名属性,但是由于是组合,这两个属性是独立的。我们用伪代码看看:

aParent = {name:’jerry’}

aChild = {__proto__:aParent, name:’frank’}

aChild中的name和aParent中的name是各自独立的。我们aChild.name=’unknown’并不会改变aParent.name。

有一点要拿出单独说说,造成迷糊的最大根源就是误解,对于如下代码:

aParent = {name:’jerry’}

aChild = {__proto__:aParent}

若我们取aChild.name的值,我们很容易resolve,那就是子域中找不到,去父域中找,找到了jerry。但是对于:aChild.name = ‘frank’这样的赋值代码我们会产生歧义(ambiguous),我们可能有两中含义:

1,更新父域中的name属性为frank。

2,设置子域中的name属性为frank。

JavaScript选用的方式是第2种。即设置(新建)子域自己的name属性为frank,并隐藏了父域中的name属性。我们通常误以为JavaScript是按1的方式工作,其实不是。

另外类(模版)其实在编程语言的实现中是可有可无的,像JavaScript压根就没有类(模版),他只有对象,new Point()只不过是一个语法糖,跟aObj = createObject()是一样的,只是调用一个方法去生成一个对象,而已。

理解JavaScript中的原型继承(2)的更多相关文章

  1. javascript中的原型继承

    在Javascript面向对象编程中,原型继承不仅是一个重点也是一个不容易掌握的点.在本文中,我们将对Javascript中的原型继承进行一些探索. 基本形式 我们先来看下面一段代码: <cod ...

  2. 理解javascript中的原型模式

    一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂 ...

  3. 如何理解JavaScript中的原型和原型链

    首先是一张关系图,避免抽象化理解时产生的困难 Function对象 函数对象是JavaScript学习中不可避免的一部分,而且这一部分相对重要且抽象 函数的创建方式有2种: 字面量创建 var foo ...

  4. javascript 中的原型继承

    javascript圆形变成的基本规则: 所有数据都是对象: 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它: 对象会记住它的原型: 如果对象无法响应某个请求,它会把这个请求委托给 ...

  5. 简单理解javascript中的原型对象,实现对之间共享属性和行为

    javascript中提供了构造函数.可以方便的创建对象. 典型的构造函数例如以下: function Person(name, age) { this.name = name; this.age = ...

  6. 深入理解JavaScript中的类继承

    由于写本文时全部是在编辑器中边写代码边写感想的,所以,全部思想都写在代码注释里面了 // 类继承 //todo.1 extends 关键字 class Animal { constructor(nam ...

  7. JavaScript中的原型继承原理

    在JavaScript当中,对象A如果要继承对象B的属性和方法,那么只要将对象B放到对象A的原型链上即可.而某个对象的原型链,就是由该对象开始,通过__proto__属性连接起来的一串对象.__pro ...

  8. Javascript中的原型继承具体解释

    js中的继承,是面向对象的知识,由于js没有类的概念.所以继承是通过对象实现的.谈到继承.就必须说到prototype,就不得不先说下new的过程. 一个小小的列子: <script type= ...

  9. 一句话简单理解javascript中的原型对象

    通过构造函数F创建的对象实例p 这个对象p的原型对象是 构造函数中prototype属性指向的对象s,这个对象p中也有个非标准的__proto__属性指向构造函数prototype属性所指向的对象s, ...

随机推荐

  1. JSP读取My SQL数据乱码问题的解决

    用jsp读取My SQL数据库里面的数据,结果读出来的是乱码,把jsp页面的charset.pageEncoding属性都改成了UTF-8,My SQL数据库的Collate属性也改成了UTF-8,还 ...

  2. iOS取得AddressBook联系人信息

    新建一个CContact类用于存放联系人信息,下面是该类的代码: CContact.h代码: 01 #import <Foundation/Foundation.h> 02   03   ...

  3. 最小生成二叉树-prim算法

    1.prim算法:一种计算生成最小生成树的方法,它的每一步都会为一棵生长中的树添加一条边. 2.时间复杂度:

  4. java servlet+mysql全过程(原创)

    前段时间写过一篇 servlet+oracle的文章,但是那是因为公司有可能接那么一个项目,然后我当时也比较闲,所以随便学了下,那玩意是白去研究了,因为公司后面并没接到那项目. 这次学servlet用 ...

  5. 第 16 章 CSS 盒模型[下]

    学习要点: 1.元素可见性 2.元素盒类型 3.元素的浮动 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 盒模型,学习怎样了解元素的外观配置以及文档的整体布局. 一.元素可见性 使用 vis ...

  6. Scalaz(55)- scalaz-stream: fs2-基础介绍,fs2 stream transformation

    fs2是scalaz-stream的最新版本,沿用了scalaz-stream被动式(pull model)数据流原理但采用了全新的实现方法.fs2比较scalaz-stream而言具备了:更精简的基 ...

  7. 《Java4Android》视频学习笔记——抽象类和抽象函数

    抽象函数的语法特征 1.类是抽象的,对象是具体的.面向对象里面有个非常重要的特征:先抽象,后具体. 2.只有函数的定义,而没有函数体的函数叫做抽象函数. abstract void fun(); ( ...

  8. PLSQL怎样导出oracle表结构和数据

    1.导出表结构和数据方式1.tools->export user objects是导出表结构 tools ->export user object 选择选项,导出.sql文件 说明:导出的 ...

  9. CSS3里的display

    默认值:inline 适用于:所有元素 继承性:无 动画性:否 none: 隐藏对象.与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间 inline: 指定对象为内联元 ...

  10. about reg

    var getR=function(str,reg){ return str.match(reg).join(""); } var a=getR("138888" ...