ES5新增函数之一: Array, JSON, String, Date

来源:互联网 发布:光纤入户家庭网络布线 编辑:程序博客网 时间:2024/05/18 00:27

ES5即ECMAScript 5.1,在JavaScript语言基础之上添加了很多新的特性,对现有的对象和语句进行相应的增强和规范,主要包括一些新增函数、对象类型增强,以及严格模式编程规范。

今天我们先来介绍以下几个新增的函数:

Array.isArray(obj);

Array.prototype.forEach();

Array.prototype.indexOf();

Array.prototype.lastIndexOf();

Array.prototype.filter();

Array.prototype.map();

Array.prototype.some();

Array.prototype.every();

Array.prototype.reduce();

JSON.parse();

JSON.stringify();

String.prototype.trim();

Date.now();

Date.prototype.toISOString();


下面我们就一一介绍他们的用法:

Array.isArray(obj);

显而易见,该函数用来判断一个对象是否为数组类型,如果是则返回true,否则返回false,我们可以用一个简单的数组来测试这个函数:

var arr = [1, 2, 3, 4, 5];var func = function() {};console.log('is arr the Array type? ', Array.isArray(arr));console.log('is func the Array type? ', Array.isArray(func));

执行上面的代码,控制台打印如下图所示:


我们可以很容易实现一个我们自己版本的isArray函数:

Array.isArray = Array.isArray || function(obj) {return Object.prototype.toString.call(obj) === '[object Array]';};


Array.prototype.forEach();

forEach函数是定义在Array原型上的一个函数,用于实现最基本的数组遍历操作,所以我们可以直接在数组上面调用实现遍历:
console.group('for each is running');[1, 2, 3, 4, 5].forEach(function(item, index, array) {console.log('the current index is: ' + index + ', value is: ' + item);});console.groupEnd();

在回调函数中,前两个参数分别表示当前的元素和索引,最后一个参数是数组本身,打印时我们使用console的group和groupEnd对控制台结果分组,代码执行完毕,结果打印如下:



Array.prototype.indexOf(); & Array.prototype.lastIndexOf();

这两个函数分别用于获取指定元素在数组中第一次出现和最后一次出现时的索引,使用方法如下:

var arr = [1, 2, 3, 4, 5, 3];//indexOfvar indexOf3 = arr.indexOf(3);console.log('the index of 3 in the array: ', indexOf3);//lastIndexOfvar lastIndexOf3 = arr.lastIndexOf(3);console.log('the last index of 3 in the array: ', lastIndexOf3);

这两个函数还可以传递第二个可选的参数,表示从指定索引开始查找。上面代码的打印结果如下:


Array.prototype.filter();

filter函数会根据回调函数指定的过滤规则对原数组进行一次过滤操作,并且返回一个新的数组,包含符合过滤条件的数组元素。例如我们想要从一个数组中过滤出所有的奇数元素,就可以使用filter函数轻松实现:

var oddArr = [1, 2, 3, 4, 5].filter(function(item) {return item % 2 !== 0;});console.log('afer filter called, got a new array with odd numbers: ', oddArr);
上面代码结果打印如下:


Array.prototype.map();
map函数会返回一个新数组,根据回调函数中对原数组元素的计算规则,将每个元素的计算结果映射到新数组对应的位置,相当于对数组整体上做了一次计算的映射,我们用下面简单的代码来解释这个操作:

var doubleArr = [1, 2, 3, 4, 5].map(function(item) {return item * 2;});console.log('after map called, got a new array with double numbers: ', doubleArr);
如上面代码所示,我们希望将原数组每个元素都变为原来的2倍,使用map函数,获取到一个新的数组,新数组内的每个元素和原数组对应的元素都存在2倍的关系,我们可以看一下控制台的打印结果:



Array.prototype.some();

some函数会返回true如果数组内的一些元素满足指定回调函数的判定规则的话,反之如果没有任何元素满足这个规则,则返回false。例如下面这段代码我们可以判断数组内是否存在一些大于3的元素:

var someoneGreaterThan3 = [1, 2, 3, 4, 5].some(function(item) {return item > 3;});console.log('are there some elements in the array which is greater than 3? ', someoneGreaterThan3);
因为数组内存在有大于3的元素,所以调用some函数预期会返回一个true,现在我们来看一下打印结果:


Array.prototype.every();

every跟some一样会返回true或false,唯一不同的是,every只有在数组内所有元素都满足判定条件时才会返回true,否则返回false。还是使用同样的数组,我们来做两次判定:

var arr = [1, 2, 3, 4, 5];var everyoneGreaterThan0 = arr.every(function(item) {return item > 0;});console.log('is that all elements are greater than 0? ', everyoneGreaterThan0);var everyoneGreaterThan3 = arr.every(function(item) {return item > 3;});console.log('is that all elements are greater than 3? ', everyoneGreaterThan3);
上面代码中我们调用了两次every函数,分别判定是否所有元素大于0,是否所有元素大于3。根据我们自己的判断,分别应该返回true和false,打印结果确是如此:


Array.prototype.reduce();
在这一系列函数里面,reduce函数算是最为复杂的一个了,不管是它的名字还是计算逻辑,初次接触时都比较难以理解。reduce在这里的意思为“降解”或“规约”,是通过一个过程把一个复杂的结果集转化成一个简单的结果,函数签名如下:

arr.reduce(callback[, initialValue])
我们可以看到,reduce函数包含两个参数,回调函数callback和初始计算值initialValue,初始计算值是可选参数,如果指定这个参数,会在第一次调用callback时参与运算,而callback函数中会有三个参数:

previousCalculatedValue: 上一次运算后结果的返回值,这个结果会作为新的初始值参与下一次运算,如果指定了initialValue,那么进行第一次运算时,previousCalculatedValue即是initialValue的值,如果没有指定initialValue,那么第一次运算时,previousCalculatedValue会是数组第一个元素的值。

currentItem: 数组内当前参加运算的元素。

array: 调用reduce的数组对象本身。

下面我们举个简单的例子来阐述一下reduce的具体计算过程,例如我们有一个数组,想要求和数组内的所有元素,可以这样调用:

var sum = [1, 2, 3, 4, 5].reduce(function(previousCalculatedValue, currentItem, index, array) {var currentSum = previousCalculatedValue + currentItem;console.log( previousCalculatedValue + ' + ' + currentItem + ' -> ' + currentSum);return currentSum;});console.log('the sum of all elements in the array: ', sum);
先来看看打印信息:

我们可以清晰的看到每一个步骤是怎么运算的,第一次运算时,初始值是数组的第一个元素,而当前值是数组的第二个元素,运算完毕,将运算结果作为下一轮运算的初始值,开始新一轮的运算,直到数组最后一个元素参加运算后,整个规约的过程才结束,同时返回运算结果。前面我们介绍到可选参数initialValue,如果指定这个参数,第一次运算时程序会使用这个初始值,当前元素会从数组内第一个元素开始,比上面的过程要多一个步骤。我们稍微改动一下代码来验证一下:

var sum = [1, 2, 3, 4, 5].reduce(function(previousCalculatedValue, currentItem, index, array) {var currentSum = previousCalculatedValue + currentItem;console.log( previousCalculatedValue + ' + ' + currentItem + ' -> ' + currentSum);return currentSum;}, 0);console.log('the sum of all elements in the array: ', sum);
我们添加了一个初始值0,在不影响运算结果的前提下,来看看它是如何运行的:

相信从这个运行结果中,大家已经看出其间的端倪了吧。
我们上面的例子是比较简单的,其实reduce可以做很多复杂的操作,例如我们有一个二维数组,需要将其降解为一个简单的数组,就可以调用reduce轻松实现:

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(previousValue, currentItem) {console.log(previousValue, currentItem);  return previousValue.concat(currentItem);}, []);console.log('after reduce called on a two-dimensional array, the result is: ', flattened);
同样我们来看看它的运行过程及结果:


除了reduce之外,还有一个函数与之相似,它就是reduceRight,唯一不同的是,它的运算方向是从数组尾部开始的,大家可以自己测试一下。

以上就是数组部分的新增函数,在开发中还是很有帮助的,如果想要对数组的操作有进一步的了解,可以移步至MDN中Array的介绍页面,在相关的新增函数介绍中,也有相应的polyfill,为低版本的浏览器提供这些函数的支持。下面是Mozilla的MDN页面:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

以上是Array部分,下面我们来介绍其他几个类的新增函数:


JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,在开发中常用于构建易于读写和传输的数据,它使用两种结构:对象和数组。

过去我们在使用JSON数据时,往往都是用第三方库来转换,随着ES5的发布,新的标准内置了JSON对象,用于JSON对象和JSON字符串之间的转换操作。JSON作为全局对象,我们可以直接调用,它有如下两个函数:

JSON.parse(string);//负责将字符串转换为JOSN对象并返回JSON.stringify(data);//负责将数据转换为JSON字符串并返回,data可以是null, boolean, number, string, JSONObject, JSONArray
下面我们就来用一个例子解释一下这两个函数的用法:
var person = {  id: 1,  name: 'Scott',  hobbies: ['basketball', 'pingpang', 'music']};var personString = JSON.stringify(person);console.log(personString);var newPerson = JSON.parse(personString);console.log(newPerson);

打印结果如下:

这里我们着重介绍一下stringify函数的使用,它提供的功能远比上面的强大,函数签名如下:

JSON.stringify(value[, replacer[, space]]);

其中value就是我们需要转换的对象,replacer可以是一个数组或者一个函数,如果传入一个数组,则相当于一个白名单,只有出现在数组中的属性名对应的键值对才会出现结果中,如果指定一个函数,我们可以实现一些逻辑来过滤或更改将要出现在结果中的数据,最后一个参数是缩进空格,我们可以指定一个数字,表示缩进几个空格,还可以指定一个字符串,表示以指定字符串代替空格出现在缩进中。下面这段代码用于将person对象转换为JSON字符串,并且要求字符串中不能出现address的信息,为了更好的可读性,以4个空格作为缩进:

var person = {  id: 1,  name: 'Scott',  hobbies: ['basketball', 'pingpang', 'music'],  address: 'Haidian, Beijing'};console.log(JSON.stringify(person, function s(key, value) {  //the 'address' property will not be in the JSON string.  if (key === 'address') return undefined;  //other properties will be returned as normal.  return value;}, 4)); //4 white spaces indent, we can also pass a '\t' or '----'

下面来看看打印结果:


String.prototype.trim();

ES5也为String类添加了一个实用的函数,即trim()函数,用于去除字符串前后多余的空白,在jQuery时代,这个方法给开发者带来了极大的便利,相信大家已经熟知它的用法了:

var trimedString = ' hello world '.trim();
我们也可以实现我们自己的trim函数:

if (!String.prototype.trim) {  String.prototype.trim = function () {    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');  };}
可能大家会好奇,上面一串正则表达式是什么东东,通常我们使用/^\s+|\s+$/g来匹配前后的空格,为什么这里还要加上后面一大串字符呢?因为ES5规定\s包含空格和换行符,而空格又包含U+FEFF和U+00A0这两个Unicode字符,下面这个表达式在控制台下运行将会返回true:

/^\s+$/.test("\ufeff\u00a0")
所以建议大家加上。


Date.now();

这个函数会返回当前时间的一个时间戳,其结果与new Date().getTime()和(+new Date)是一样的,大家可以试一下。

Date.prototype.toISOString();

toISOString函数会返回一个ISO格式的字符串来表示当前的时间,格式为YYYY-MM-DDTHH:mm:ss.sssZ,表示的时间统一为0时区标准时间,后面的Z也是Zero的意思。


1 0
原创粉丝点击