假设想给上节讲的场景图库添加收集诊断信息的功能。这对于调试和性能分析很有用。

38条示例

给每个Actor实例一个唯一的标识数。

添加标识数

function Actor(scene,x,y){
this.scene=scene;
this.x=x;
this.y=y;
this.id=++Actor.nextID;
scene.register(this);
}
Actor.nextID=0;

现在我们需要对Actor的子类做同样的事。假设,Alien类代表太空飞船的敌人。除了其角色标识数外,我们希望每个外星人都有一个单独标识数。

function Alien(scene,x,y,direction,speed,strength){
Actor.call(this,scene,x,y);
this.direction=direction;
this.speed=speed;
this.strength=0;
this.damage=0;
this.id=++ Alien.nextID;
}
Alien.nextID=0;

这里导致Alien类与其父类Actor之间冲突。两个类都试图给实例属性id写数据。虽然每个类都认为该属性是“私有”的(即只有直接定义在该类中的方法才能获取该属性),然而事实是该属性存储在实例对象上并命名为一个字符串。如果在继承体系中的两个类指向相同的属性名,那么它们指向的是同一个属性。

执行

当我们调用下面这个代码来看一下,上面的执行过程。

var alien=new Alien(scene,0,0,'lt',100,10);

这个时候,首先调用Alien构造函数运行,创建一个空对象alien,把构造函数中的this绑定到alien上,然后运行Actor.call(alien,scene,0,0)产生了alien.id=++Actor.nextID,然后添加其它私有属性,但当又遇到id这个属性的时候,alien.id=++Alien.nextID,把上面从基类构造函数产生的id进行了修改。这个时候,id的属性就产生了歧义。

修正

因此,子类必须始终留意其父类使用的所有属性,即使那些属性在概念上是私有的。该例子显而易见的解决方法是对Actor标识数和Alien标识数使用不同的属性名。

function Actor(scene,x,y){
this.scene=scene;
this.x=x;
this.y=y;
this.id=++Actor.nextID;
scene.register(this);
}
Actor.nextID=0; function Alien(scene,x,y,direction,speed,strength){
Actor.call(this,scene,x,y);
this.direction=direction;
this.speed=speed;
this.strength=0;
this.damage=0;
this.alienID=++ Alien.nextID;
}
Alien.nextID=0;

提示

  • 留意父类使用的所有属性名

  • 不要在子类中重用父类的属性名

附录:完整结构关系图

下面是一张38条和39条里添加标识符后,所有类之间的关系图。

[Effective JavaScript 笔记]第39条:不要重用父类的属性名的更多相关文章

  1. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  2. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  3. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  4. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  5. [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染

    之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...

  6. [Effective JavaScript 笔记]第20条:使用call方法自定义接收者来调用方法

    不好的实践 函数或方法的接收者(即绑定到特殊关键字this的值)是由调用者的语法决定的.方法调用语法将方法被查找的对象绑定到this变量,(可参阅之前文章<理解函数调用.方法调用及构造函数调用之 ...

  7. [Effective JavaScript 笔记]第47条:绝不要在Object.prototype中增加可枚举的属性

    之前的几条都不断地重复着for...in循环,它便利好用,但又容易被原型污染.for...in循环最常见的用法是枚举字典中的元素.这里就是从侧面提出不要在共享的Object.prototype中增加可 ...

  8. [Effective JavaScript 笔记]第55条:接收关键字参数的选项对象

    53节建议保持参数顺序的一致约定对于帮助程序员记住每个参数在函数调用中的意义很重要.参数较少这个主意不错,但如果参数过多后,就出现麻烦了,记忆和理解起来都不太容易. 参数蔓延 如下面这些代码: var ...

  9. [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑

    构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...

随机推荐

  1. IOS判断app在appstore是否有可用的更新

    iTunes可以提供app的版本信息,主要通过appid获取,如 http://itunes.apple.com/lookup?id=946449501,使用时只需要到iTunes查找自己的appid ...

  2. C# 6.0部分新特性

    Struct的默认构造函数和属性赋值 我看C# 6 introduce 提到这个功能.但vs2015搭载的NET4.6貌似还不支持这个.所以也不好判断. 属性赋值 /// <summary> ...

  3. Go-MySQL-Driver:一个Go语言的轻量级极速的mysql驱动

    Go语言的 database/sql 包的一个 MySQL驱动. 特性 轻量级与快速 原生Go语言,没有C绑定,只有纯Go 没有不安全的操作(类型转换等) 动态处理崩溃的连接 动态连接池 支持大于16 ...

  4. nginx 出现413 Request Entity Too Large问题的解决方法

    nginx 出现413 Request Entity Too Large问题的解决方法 使用php上传图片(大小1.9M),出现 nginx: 413 Request Entity Too Large ...

  5. 关于js字符串替换的一道笔试题目

    题目描述 请写出一个字符串转换函数,接受两个参数: 1.字符串 形如{a}ab-{b}cde{c}fff{d}{}: 2.对象,形如{'a':'1','b':'2','d':'4'} 根据,对象的属性 ...

  6. Beta 分工比例

    组员在Beta版本的分工和个人贡献百分比. 人员 任务完成情况 贡献比 031302331 闹钟,爬取知乎数据,书籍下载,解决bug,帮助队友 25% 031302442 注册登录逻辑,书籍评论评分页 ...

  7. js库中$冲突的解决方法

    http://www.w3school.com.cn/jquery/core_noconflict.asp

  8. Maven-改变本地存储仓库位置

    修改 maven 仓库存放位置: 找到 maven 下的 conf 下的 settings.xml 配置文件,假设maven安装在D:\Server目录中.那么配置文件应该在 D:\Server\ma ...

  9. Linux operation strucutre

    Under the /usr/src directory. 1.arch目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CP ...

  10. jQuery插件开发详细教程

    这篇文章主要介绍了jQuery插件开发详细教程,将概述jQuery插件开发的基本知识,最佳做法和常见的陷阱,需要的朋友可以参考下 扩展jQuery插件和方法的作用是非常强大的,它可以节省大量开发时间. ...