《javaScript高级程序设计》读书笔记(六)

以下内容可能存在个人理解的部分,并非完全参照原文

如有疑问,请以书中内容为准

接着上一篇的内容

第五章 引用类型

对象是引用类型的实例

5.1 Object类型

用对象字面量表示法创建的是Object的实例

一般来说,访问对象属性时使用的都是点表示法。不过,在JavaScript当中也可以使用方括号来访问对象的属性。

方括号语法的优点是可以通过变量来访问属性,例如

var propertyName = "name";
alert(person[propertyName]);

5.2 Array类型

数组可以说是面试必问了

ECMAScript数组的每一项可以保存任何类型的数据,而且数组大小是可以动态调整的。

var colors = new Array();
var colors = new Array(20);
var colors = new Array("red","blue","green");

也可以省略new操作符

var colors = Array(3);
var names = Array("Greg");

这里其实有一个问题,我们知道new会在这个函数的原型上构造一个对象,然后最后返回这个对象,那么这里的Array函数究竟做了什么呢?为什么可用new也可以不用

也可以用字面量表示法

var colors = ["red","blue","green"];
var names = [];

用方括号访问数组时,如果这个值存在则会返回对应项的值,如果是设置数组则会改变这个值

var colors = ["red","blue","green"];
alert(colors[0]);
colors[2] = "black";
colors[3] = "brown";
alert(colors); //  red,blue,green,brown

如果值不存在则会扩充数组长度,并添加这个值

当把一个值放在超出当前数组大小的位置上时,数组就会重新计算其长度值

var colors = ["red","blue","green"];
colors[99] = "black";
alert(colors.length); // 100

中间生成的项会被设置为undefined

数组的length是可以被修改的

var colors = ["red","blue","green"];
colors.length = 2;
alert(colors[2]); // undefined

如果减少数组的length,那么多出来的项将会被移除

同理如果增加length,会在数组后新增项

检测数组

经典问题,被问过两次了

在一般情况下,使用instanceof操作符就可以检测数组

但是instanceof操作符假定只存在一个全局执行环境

如果网页中包含多个frame,那么实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果你从第一个frame向另一个frame传一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。

为了解决这个问题,ES5新增了Array.isArray()方法可以判断一个值是不是数组,而不管它是在哪个全局环境中创建的。

还可以使用Object.prototype.toString.call(value)的方法检测数组

转换方法

所有对象都具有toLocaleString()toString()valueOf()方法

这里的说法是否太绝对呢?暂且保留这个疑问

其中,调用valueOf()返回的还是数组本身,而调用数组的toString()方法会返回由数组中每个值调用toString()并使用逗号分隔符拼接而成的字符串。

var colors = ["red","blue","green"];
alert(colors.toString());   // red,blue,green
alert(colors.valueOf());    // red,blue,green
alert(colors);              // red,blue,green

由于alert()要接受字符串参数,所以它会在后台调用toString()方法

另外,toLocaleString()方法经常也会返回与toString()valueOf()方法相同的值

区别是,当数组调用toLocaleString()方法时,它的每一项调用的是toLocaleString()方法

数组继承的toLocaleString()toString()方法在默认情况下都会以逗号分隔字符串的形式返回,而如果使用join()方法,则可以使用不同的分隔符

var colors = ["red","green","blue"];
alert(colors.join(","));    // red,green,blue
alert(colors.join("||"));   // red||green||blue

栈方法

栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构,也就是最新添加的项最早被移除。

ECMAScript为数组专门提供了push()pop()方法,以便实现类似栈的行为

push()方法可以接收任意数量的参数,并把它们逐个添加到数组末尾,并返回修改后数组的长度。而pop()方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。

var colors = new Array();
var count = colors.push("red","green");
alert(count);   //  2

count = colors.push("black");
alert(count);   //  3

var item = colors.pop();
alert(item);            //  "black"
alert(colors.length);   //  2

队列方法

队列数据结构的访问规则是FIFO(First-In-First-Out,先进先出)。队列在列表的末端添加项,从列表的前端移除项。

shift()方法能够移除数组中的第一项并返回该项,同时将数组长度减1

结合shift()push()方法,可以像使用队列一样使用数组

var colors = new Array();
var count = colors.push("red","green");
alert(count);   // 2

count = colors.push("black");
alert(count);   // 3

var item = colors.shift();
alert(item);            // "red"
alert(colors.length);   // 2

ECMAScript还为数组提供了一个unshift()方法,与shift()用途相反:它能在数组前端添加任意个项并返回新数组的长度。因此,同时使用unshift()pop()方法,可以从相反的方向来模拟队列。

重排序方法

数组当中存在两个可以直接用来重排序的方法:reverse()sort()

reverse()方法会反转数组项的顺序

var values = [1,2,3,4,5];
values.reverse();
alert(values);  // 5,4,3,2,1

在默认情况下,sort()方法按升序排列数组项。为了实现排序,sort()会调用每个数组项的toString()方法,然后比较得到的字符串。

注意:即使数组的每一项都是数值,sort()方法比较的也是字符串

var values = [0,1,5,10,15];
values.sort();
alert(values);  //0,1,10,15,5

这样不是我们想要的结果。因此sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值前面。

function compare(value1,value2){
    if(value1 < value2){
        return -1;  // value1位于value2前面
    }else if( value1 > value2){
        return 1;   // value1位于value2后面
    }else{
        return 0;
    }
}

reverse()sort()方法返回的是排序后的数组

对于数值类型或其valueOf()方法会返回数值类型的对象类型,可以使用一个更简单的比较函数。

function compare(value1,value2){
    return value2 - value1;
}

操作方法

concat()方法会创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。

var colors = ["red","green","blue"];
var colors2 = colors.concat("yellow",["black","brown"]);

alert(colors);      // red,green,blue
alert(colors2);     // red,green,blue,yellow,black,brown

slice()方法能够基于当前数组中的一或多个项创建一个新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。

var colors = ["red","green","blue"]
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);

alert(colors2); // green,blue,yellow,purple
alert(colors3); // green,blue,yellow

如果slice()方法的参数中有一个负数,则用数组长度加上该数来确定相应的位置。如果结束位置小于起始位置,则返回空数组。

splice()方法有很多种使用方式:

  • 删除:传入要删除的第一项的位置和要删除的项数。如splice(0,2)
  • 插入:传入起始位置、0(删除0项)和要插入的项。如splice(2,0,"red")
  • 替换:传入起始位置、要删除的项数和插入项。如splice(2,1,"red")

splice()方法始终会返回一个数组,为从原始数组中删除的项(没有则返回空数组)。

位置方法

ES5添加了两个位置方法:indexOf()lastIndexOf()

indexOf()从数组开头开始查找,lastIndexOf()方法从数组末尾向前查找

两个方法都返回要查找的项在数组中的位置,没找到则返回-1。

在比较时会使用全等操作符

迭代方法

ES5为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和运行该函数的作用域对象(可选)。

什么时候需要传入作用域对象呢?

  • every():对数组中的每一项运行给定函数,如果函数对每一项都返回true,则返回true
  • filter():返回该函数
  • forEach():对数组中的每一项运行给定函数,没有返回值
  • map():返回每次函数调用的结果组成的数组
  • some():如果函数对任一项返回true,则返回true

传入的函数会接收三个参数:数组项的值、该项在数组中的位置和数组本身。

这一般会在forEach()中用到

var numbers = [1,2,3,4,5,6,1,2,3];

numbers.forEach(function(item,index){
    //do something
});

归并方法

ES5还新增了两个归并数组的方法:reduce()reduceRight()

reduce()是从左到右遍历数组,reduceRight()是从右到左

这两个方法都接收两个参数:一个在每一项上调用的函数和作为归并基础的初始值(可选)。

传入的函数接收4个参数:前一个值、当前值、项的索引和数组对象。

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index){
    return prev + cur;
})

这里第一次执行prev是1,cur是2,也就是说没有默认值时第一项被当成了默认值

别问我怎么知道的,试出来的

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,191评论 0 4
  •   引用类型的值(对象)是引用类型的一个实例。   在 ECMAscript 中,引用类型是一种数据结构,用于将数...
    霜天晓阅读 1,028评论 0 1
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,074评论 0 21
  • 第5章 引用类型 引用类型的值(对象)是引用类型的一个示例。在ECMAScript 中,引用类型是一种数据结构,用...
    力气强阅读 700评论 0 0
  • 一个人穷不可怕,怕的是没有上进的心没有积极想办法挣钱的头脑,而是在一味的埋怨客观条件,怨自己没有好的家庭背景,...
    馨雨轩阅读 265评论 2 2