Thee(你) I’ll chase(追逐;追捕) hence(因此;今后), thou(你;尔,汝) wolf in sheep’s array.
—William Shakespeare, The First Part of Henry the Sixth
An array is a linear(线的,线型的;直线的,线状的;长度的) allocation(分配,配置;安置) of memory in which elements are accessed by integers that are used to compute offsets. Arrays can be very fast data structures. Unfortunately, JavaScript does not have anything like this kind of array.

Instead, JavaScript provides an object that has some array-like characteristics. It converts array subscripts(下标) into strings that are used to make properties. It is significantly slower than a real array, but it can be more convenient to use. Retrieval and updating of properties work the same as with(正如) objects, except that there is a special trick with integer property names. Arrays have their own literal format. Arrays also have a much more useful set of built-in methods, described in Chapter 8.

Array Literals

Array literals provide a very convenient notation(记号法) for creating new array values. Anarray literal is a pair of(一对,一副) square brackets surrounding zero or more values separated by commas. An array literal can appear anywhere an expression can appear. The first value will get the property name '0', the second value will get the property name '1', and so on:

> var empty = [];
undefined
> var numbers = [
... 'zero', 'one', 'two', 'three', 'four',
... 'five', 'six', 'seven', 'eight', 'nine'
... ];
undefined
> empty[1] // undefined
undefined
> numbers[1] // 'one'
'one'
> empty.length //
0
> numbers.length //
10

The object literal:

> var numbers_object = {
... '0': 'zero', '1': 'one', '2': 'two',
... '3': 'three', '4': 'four', '5': 'five',
... '6': 'six', '7': 'seven', '8': 'eight',
... '9': 'nine'
... };
undefined
> numbers_object[0]
'zero'

produces a similar result. Both numbers and number_object are objects containing 10 properties, and those properties have exactly the same names and values. But there are also significant differences. numbers inherits from Array.prototype, whereas number_object inherits from Object.prototype,so numbers inherits a larger set of useful methods. Also, numbers gets the mysterious length property, while number_object does not.

In most languages, the elements of an array are all required to be of the same type.JavaScript allows an array to contain any mixture of values:

> var misc = [
... 'string', 98.6, true, false, null, undefined,
... ['nested', 'array'], {object: true}, NaN,
... Infinity
... ];
undefined
> misc.length //
10
> misc.string
undefined
> misc['string']
undefined
> misc[0]
'string'

Length

Every array has a length property. Unlike most other languages, JavaScript’s array length is not an upper bound. If you store an element with a subscript that is greater than or equal to the current length, the length will increase to contain the new element. There is no array bounds error.

The length property is the largest integer property name in the array plus one. This is not necessarily the number of properties in the array:

> var myArray = [];
undefined
> myArray.length //
0
> myArray[1000000] = true;
true
> myArray.length //
1000001
> // myArray contains one property.
undefined

The [] postfix subscript(下标) operator converts its expression to a string using the expression’s toString method if it has one. That string will be used as the property name. If
the string looks like a positive integer that is greater than or equal to the array’s current length and is less than 4,294,967,295, then the length of the array is set to the new subscript plus one.

> myArray[0] = 100
100
> myArray[0]
100
> myArray['0']
100
> myArray['0'] = 9
9
> myArray['0']
9
> myArray[0]
9

The length can be set explicitly. Making the length larger does not allocate more space for the array. Making the length smaller will cause all properties with a subscript that is greater than or equal to the new length to be deleted:

> numbers.length = 10
10
> numbers
[ 'zero',
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine' ]
> numbers.length = 11
11
> numbers
[ 'zero',
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
]
> numbers.length = 3
3
> numbers
[ 'zero', 'one', 'two' ]

A new element can be appended to the end of an array by assigning to the array’s current length:

> numbers[numbers.length] = 'shi'
'shi'
> numbers
[ 'zero',
'one',
'two',
'shi' ]

It is sometimes more convenient to use the push method to accomplish the same thing:

> numbers.push('go')
5
> numbers
[ 'zero',
'one',
'two',
'shi',
'go' ]

Delete

Since JavaScript’s arrays are really objects, the delete operator can be used to remove elements from an array:

> delete numbers[2]
true
> numbers
[ 'zero',
'one',
,
'shi',
'go' ]

Unfortunately, that leaves a hole in the array. This is because the elements to the right of the deleted element retain their original names. What you usually want is to decrement the names of each of the elements to the right.

Fortunately, JavaScript arrays have a splice method. It can do surgery(外科;外科手术) on an array,deleting some number of elements and replacing them with other elements. The first
argument is an ordinal(序数) in the array. The second argument is the number of elements to delete. Any additional arguments get inserted into the array at that point:

> numbers.splice(2,1)
[ ]
> numbers
[ 'zero',
'one',
'shi',
'go' ]
> numbers.splice(2,1,'two')
[ 'shi' ]
> numbers
[ 'zero',
'one',
'two',
'go' ]

The property whose value is 'shi' has its key changed from '4' to '3'. Because every property after the deleted property must be removed and reinserted with a new key,this might not go quickly for large arrays.

Enumeration

Since JavaScript’s arrays are really objects, the for in statement can be used to iterate over all of the properties of an array. Unfortunately, for in makes no guarantee about the order of the properties, and most array applications expect the elements to be produced in numerical order. Also, there is still the problem with unexpected properties being dredged up(疏浚;回忆起) from the prototype chain.

Fortunately, the conventional(符合习俗的,传统的;常见的;惯例的) for statement avoids these problems. JavaScript’s for statement is similar to that in most C-like languages. It is controlled by three clauses—the first initializes(初始化) the loop, the second is the while condition, and the third does the increment:

> myArray = [1,2,3,4,5,6,7]
[ 1,
2,
3,
4,
5,
6,
7 ]
> var i;
undefined
> for (i = 0; i < myArray.length; i += 1) {
... console.log(myArray[i]);
... }
1
2
3
4
5
6
7
undefined//这个是node.js控制台输出的,因为循环语句并没有返回值

Confusion

A common error in JavaScript programs is to use an object when an array is required or an array when an object is required. The rule is simple: when the property names are small sequential integers, you should use an array. Otherwise, use an object.

JavaScript itself is confused about the difference between arrays and objects. The typeof operator reports that the type of an array is 'object', which isn’t very helpful.

> typeof myArray
'object'

JavaScript does not have a good mechanism for distinguishing between arrays and objects. We can work around that deficiency(缺陷,缺点;缺乏;不足的数额) by defining our own is_array function:

var is_array = function (value) {
return value &&
typeof value === 'object' &&
value.constructor === Array;
};
> var is_array = function (value) {
... return value &&
... typeof value === 'object' &&
... value.constructor === Array;
... };
undefined
> is_array(myArray)
true

Unfortunately, it fails to identify arrays that were constructed in a different window or frame. If we want to accurately detect those foreign arrays, we have to work a little harder:

var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};

具体原因请查阅:http://stackoverflow.com/questions/11597583/why-are-cross-frame-or-window-arrays-in-javascript-so-hard-to-identify

下面对要这样做的原因做一个探讨:

two_windown.html

<html>
<script type="text/javascript">
function is_array(value) {
return value &&
typeof value === 'object' &&
value.constructor === Array;
};
myArray = [1,2,3,4,5];
alert("father windown:" + is_array(myArray)); child = window.open('child_windown.html', 'newwindow', 'height=100, width=400, top=0,left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no') </script>
</html>

child_windown.html

<html>
<script type="text/javascript">
myArray = [1,2,3,4,5];
var obj=window.opener;
alert(obj);
alert("son windown:" + obj.is_array(myArray));//false
</script>
</html>

以上两个文件请务必放在服务器上

First, we ask if the value is truthy. We do this to reject null and other falsy values.Second, we ask if the typeof value is 'object'. This will be true for objects, arrays,and (weirdly) null. Third, we ask if the value has a length property that is a number.This will always be true for arrays, but usually not for objects. Fourth, we ask if the value contains a splice method. This again will be true for all arrays. Finally, we ask if the length property is enumerable (will length be produced by a for in loop?).That will be false for all arrays. This is the most reliable test for arrayness that I have found. It is unfortunate that it is so complicated.

Having such a test, it is possible to write functions that do one thing when passed a single value and lots of things when passed an array of values.

Methods

JavaScript provides a set of methods for acting on arrays. The methods are functions stored in Array.prototype. In Chapter 3, we saw that Object.prototype can be augmented. Array.prototype can be augmented as well.

For example, suppose we want to add an array method that will allow us to do computation on an array:

永远要记住javascript中的数组只是一个对象而已

JavaScript- The Good Parts Chapter 6的更多相关文章

  1. JavaScript: The Evil Parts - 1

    最近在看JavaScript框架设计,在讲解类型判定的时候提到了一些“匪夷所思的情况”,不过没有明说都是什么时候会出现这些情况.自己玩儿了一下,写写随笔吧.不过可能除了我找到的,还有会其他时候会出现这 ...

  2. JavaScript- The Good Parts CHAPTER 2

    I know it well:I read it in the grammar long ago.—William Shakespeare, The Tragedy(悲剧:灾难:惨案) of Titu ...

  3. JavaScript- The Good Parts Chapter 5 Inheritance

    Divides one thing entire to many objects;Like perspectives, which rightly gazed uponShow nothing but ...

  4. JavaScript- The Good Parts Chapter 4

    Why, every fault’s condemn’d ere it be done:Mine were the very cipher of a function. . .—William Sha ...

  5. JavaScript: The Good Parts

    Chapter 1 Good Parts: JavaScript is an important language because it is the language of the web brow ...

  6. 读 《JavaScript: The Good Parts》 有感

    提炼出一门语言或技术的 Good Parts, 使用该子集去构造健壮稳固的应用. 我们总是倾向于去学习和使用所有的语言特性,好像凡是新的,凡是提供了的, 就有必要去使用: 这本书告诉我们, 要有选择性 ...

  7. JavaScript- The Good Parts Chapter 3 Objects

    Upon a homely object Love can wink.—William Shakespeare, The Two Gentlemen of Verona The simple type ...

  8. 《JavaScript高级程序设计》chapter 1: javascript 简介

    1.2.2 文档对象模型     DHTML的出现让开发人员无需重新加载页面就可以修改其外观了. 1.2.3 浏览器对象模型(BOM)     BOM真正与众不同的地方在于他作为javascript实 ...

  9. 我要成为前端工程师!给 JavaScript 新手的建议与学习资源整理

    来源于:http://blog.miniasp.com/post/2016/02/02/JavaScript-novice-advice-and-learning-resources.aspx 今年有 ...

随机推荐

  1. 我的PHP之旅--PHP的判断、循环语句

    if语句 <?php if ($a = "some string") { // 就算括号中不是bool值,php也会自动转换为bool值 上一节写过各个类型转换bool值 / ...

  2. 创建共享内存函数CreateFileMapping()详解

    测试创建和打开文件映射的时候老是得到"句柄无效"的错误, 仔细看了MSDN以后才发觉是函数认识不透, 这里把相关的解释翻译出来 HANDLE CreateFileMapping( ...

  3. caffe之(五)loss层

    在caffe中,网络的结构由prototxt文件中给出,由一些列的Layer(层)组成,常用的层如:数据加载层.卷积操作层.pooling层.非线性变换层.内积运算层.归一化层.损失计算层等:本篇主要 ...

  4. SanDisk SecureAccess™ Software

    买了一个sandisk 的u盘,配套软件有空可以研究一下. QuickStartGuide_SanDiskSecureAccessV2.0.pdf http://www.sandisk.com/pro ...

  5. c++重载与覆写

    重载:指子类改写了父类的方法,覆写:指同一个函数,同样的参数列表,同样的返回值的,但是函数内部的实现过程不同. 重载: 1.方法名必须相同. 2.参数列表必须不相同,与参数列表的顺序无关. 3.返回值 ...

  6. 再eclipse的javaweb项目中添加JQuery文件时jquery-2.1.4.min.js报错

    解决方法: eclipse导入jquery包后报错,下面有个不错的解决方法,需要的朋友可以参考下 eclipse导入jquery包后报错,处理步骤如下: 1.打开项目.project文件,去掉如下内容 ...

  7. oracle----复制表中的数据

    两种方法: 1. 在创建表的时候将数据从其他表中复制过来(并且表的结构也复制过来): 语法: CREATE TABLE table_name AS SELECT column1,......|* FR ...

  8. jQuery.Validate自定义规程的使用案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. easyui源码翻译1.32--Combo(自定义下拉框)

    前言 扩展自$.fn.validatebox.defaults.使用$.fn.combo.defaults重写默认值对象.下载该插件翻译源码 自定义下拉框显示一个可编辑的文本框和下拉面板在html页面 ...

  10. TYPEC 接口芯片CC逻辑原理与必要性

    USB Type-C凭借其自身强大的功能,在Apple,Intel,Google等厂商的强势推动下,必将迅速引发一场USB接口的革命,并将积极影响我们日常生活的方方面面.为了能够使自己的设备兼容这些接 ...