Effective JavaScript Item 40 避免继承标准类型
本系列作为Effective JavaScript的读书笔记。
ECMAScript标准库不大。可是提供了一些重要的类型如Array,Function和Date。在一些场合下。你或许会考虑继承当中的某个类型来实现特定的功能。可是这样的做法并不被鼓舞。
比方为了操作一个文件夹。能够让文件夹类型继承Array类型例如以下:
function Dir(path, entries) {
this.path = path;
for (var i = 0, n = entries.length; i < n; i++) {
this[i] = entries[i];
}
}
Dir.prototype = Object.create(Array.prototype);
// extends Array var dir = new Dir("/tmp/mysite", ["index.html", "script.js", "style.css"]);
dir.length; // 0
可是能够发现。dir.length的值是0,而不是期待中的3。
发生这样的现象的原因在于:仅仅有当对象是真正的Array类型时,length属性才会起作用。
在ECMAScript标准中。定义了一个不可见的内部属性被称为
[[class]]。该属性的值仅仅是一个字符串,所以不要被误导觉得JavaScript也实现了自己的类型系统。所以,对于Array类型,这个属性的值就是“Array”。对于Function类型。这个属性的值就是“Function”。下表是ECMAScript定义的全部[[class]]
值:
那么当对象的类型确实是Array时,length属性的特别之处就在于:length的值会和该对象中被索引的属性个数保持一致。比方对于一个数组对象arr。arr[0]和arr[1]就表示该对象有两个被索引的属性。那么length的值就是2。当加入了arr[2]的时候。length的值会被自己主动同步成3。
相同地,当设置length值为2时。arr[2]会被自己主动设置成undefined。
可是当继承Array类型并创建实例时,该实例的
[[class]] 属性并非Array。而是Object。因此length属性不能正确的工作。
在JavaScript中,也提供了用于查询
[[class]] 属性的方法,即使用Object.prototype.toString方法:
var dir = new Dir("/", []);
Object.prototype.toString.call(dir); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
因此,更好的实现方法是使用组合而不是继承:
function Dir(path, entries) {
this.path = path;
this.entries = entries; // array property
}
Dir.prototype.forEach = function(f, thisArg) {
if (typeof thisArg === "undefined") {
thisArg = this;
}
this.entries.forEach(f, thisArg);
};
以上代码将不再使用继承。而是将一部分功能代理给内部的entries属性来实现。该属性的值是一个Array类型对象。
ECMAScript标准库中,大部分的构造函数都会依赖内部属性值如 [[class]]
来实现正确的行为。对于继承这些标准类型的子类型。无法保证它们的行为是正确的。
因此。不要继承ECMAScript标准库中的类型如:
Array。
Boolean,
Date,
Function。
Number,RegExp,String
总结
- 继承标准类型可能会导致子类的行为不对,由于标准类型会依赖于内部属性诸如 [[class]]
- 优先使用组合的方式来实现功能。而不是使用继承。
Effective JavaScript Item 40 避免继承标准类型的更多相关文章
- Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...
- Effective JavaScript Item 39 绝不要重用父类型中的属性名
本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ...
- Effective JavaScript Item 51 在类数组对象上重用数组方法
Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...
- Effective JavaScript Item 30 理解prototype, getPrototypeOf和__proto__的不同
本系列作为Effective JavaScript的读书笔记. prototype,getPropertyOf和__proto__是三个用来訪问prototype的方法.它们的命名方式非常类似因此非常 ...
- Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数
作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__
本系列作为Effective JavaScript的读书笔记. 在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API.可是在非常多运行环境中.也提供了一个特殊的_ ...
- Effective JavaScript Item 49 对于数组遍历,优先使用for循环,而不是for..in循环
本系列作为Effective JavaScript的读书笔记. 对于以下这段代码,能看出最后的平均数是多少吗? var scores = [98, 74, 85, 77, 93, 100, 89]; ...
- Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...
随机推荐
- AC自动机笔记
AC自动机 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> ...
- UVA-1331 Minimax Triangulation 区间dp 计算几何 三角剖分 最大三角形最小化
题目链接:https://cn.vjudge.net/problem/UVA-1331 题意 给一个任意多边形,把它分为多个三角形. 求某方案中最大的三角形是各方案中最小的面积的三角形面积. 思路 学 ...
- ActiveMQ:JMS开源框架入门介绍
介绍基本的JMS概念与开源的JMS框架ActiveMQ应用,内容涵盖一下几点: 基本的JMS概念 JMS的消息模式 介绍ActiveMQ 一个基于ActiveMQ的JMS例子程序 一:JMS基本概念 ...
- Java将WKT格式的Geomotry转换成GeoJSON
一.Meven添加依赖 <!-- 引入json处理包 --> <dependency> <groupId>com.alibaba</groupId> & ...
- 紫书 习题 11-8 UVa 1663 (最大流求二分图最大基数匹配)
很奇怪, 看到网上用的都是匈牙利算法求最大基数匹配 紫书上压根没讲这个算法, 而是用最大流求的. 难道是因为第一个人用匈牙利算法然后其他所有的博客都是看这个博客的吗? 很有可能-- 回归正题. 题目中 ...
- C++容器(五):set类型
set类型 map容器是键-值对的集合,好比以任命为键的地址和电话号码.而set容器只是单纯的键的集合.当只想知道一个值是否存在时,使用set容器是最适合. 使用set容器必须包含set头文件: #i ...
- POJ——T2446 Chessboard
http://poj.org/problem?id=2446 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18560 ...
- [读书]Python学习手冊--属性管理1
属性管理-特性 一般开发这不必关心属性的实现.对工具的构建这来说,了解这一块对API的灵活性有帮助. 大多数情况下,属性位于对象自身之中.或者继承自对象所派生自的一个类. ----python学习手冊 ...
- Node.js 博客实例(十)pv统计和留言统计
原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第十章,因为版本号等的原因,在原教程基础上稍加修改就可以实现. post.js中将var post={ ...
- 【数据压缩】JPEG标准与原理解析
转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/50392230 CSDN-勿在浮沙筑高台 为了满足不同应用的需求,JPEG标准包 ...