- let和const
- 变量的解构赋值
- 字符串的扩展
- 正则的扩展
- 数值的扩展
- 数组的扩展
- 函数的扩展
- 对象的扩展
一、let和const
解决了var变量提升的问题。
是一种简洁地解决闭包问题的方法。
块级作用域内有效。
二、变量的解构赋值
数组的解构
对象的解构
注意:
let {dataSource}=data;
//等价于
let {dataSourcce:dataSource}=data;
//实质是将data对象中的dataSource属性的值赋值给属性值变量dataSource
//即
let {dataSource:val}=data;
//实际是给val变量赋值
三、字符串的扩展
字符串的扩展为String类型扩展了一些方法,涉及Unicode感觉不常用就不记录了。主要记录常用的方法和模板字符串。
1.扩展的API
方法 | 使用 | 说明 | 备注 |
---|---|---|---|
includes() | str1.includes(str2[,num]) | 返回布尔值,表示是否找到了参数字符串 | 支持第二个参数,表示开始搜索的位置。针对从第n个位置直到字符串结束。 |
startsWith() | str1.startsWith(str2[,num]) | 返回布尔值,表示参数字符串是否在源字符串的头部 | 支持第二个参数,表示开始搜索的位置。针对从第n个位置直到字符串结束。 |
endsWith() | str1.endsWith(str2[,num]) | 返回布尔值,表示参数字符串是否在源字符串的尾部 | 支持第二个参数,表示开始搜索的位置。针对前n个字符。 |
repeat() | str.repeat(num) | 返回一个新字符串,表示将原字符串重复n次 | (1) 参数如果是小数,会被取整。(2) 如果repeat的参数是负数或者Infinity,会报错。(3) 参数NaN等同于0。如果repeat的参数是字符串,则会先转换成数字。 |
padStart() / padEnd() | str1.padStart(num, str2) / str1.padEnd(num, str2) | 第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。如果某个字符串不够指定长度,会在头部 / 尾部补全。 | ES7。(1) 如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。(2) 如果用来补全的字符串与原字符串,两者的长度之和超过了指定的最小长度,则会截去超出位数的补全字符串。(3) 如果省略第二个参数,则会用空格补全长度。 |
raw() | String.raw 带反引号的字符串 / String.raw({ raw: 'test' }, 0, 1, 2); <=> String.raw({ raw: ['t','e','s','t'] }, 0, 1, 2); 返回值为’t0e1s2t’ | 用来充当模板字符串的处理函数,返回一个斜杠都被转义的字符串,对应于替换变量后的模板字符串。 | 如果原字符串的斜杠已经转义,那么String.raw不会做任何处理。 |
2.模板字符串
是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
- 如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。
- 如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
- 如果你不想要换行,可以使用trim方法消除它。
- 模板字符串之中还能调用函数。
// 普通字符串
`In JavaScript '\n' is a line-feed.`
// 多行字符串
`In JavaScript this is
not legal.`
// 字符串中嵌入变量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
//反斜杠转义
var greeting = `\`Yo\` World!`;
//使用函数
function fn() { return "Hello World"; }
`foo ${fn()} bar` // foo Hello World bar
四、正则的扩展
Unicode相关不记录了。
1.修饰符的扩展
修饰符 | 说明 |
---|---|
u | 含义为“Unicode模式”,用来正确处理大于\uFFFF的Unicode字符。 |
y | 全局匹配,确保匹配必须从剩余的第一个位置开始。 |
s | dotAll 模式,使得.可以匹配任意单个字符。 |
2.正则属性的扩展
正则属性 | 说明 |
---|---|
sticky | 表示是否设置了y修饰符。 |
flags | 返回正则表达式的修饰符。 |
dotAll | 返回一个布尔值,表示该正则表达式是否处在dotAll模式。 |
五、数值的扩展
ES6为Math扩展了很多方法;ES7新增的指数运算符(**);二进制和八进制表示法,不常用就不记录了。这里只记录Number的扩展。
1.扩展的方法
方法 | 说明 | 备注 |
---|---|---|
Number.isFinite() | 用来检查一个数值是否为有限的 | 与传统的全局方法isFinite()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而新方法只对数值有效,非数值一律返回false。 |
Number.isNaN() | 用来检查一个值是否为NaN | 与传统的全局方法isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而新方法只对数值有效,非数值一律返回false。 |
Number.parseInt() | 取整 | 将全局方法parseInt()移植到Number对象上面,行为完全保持不变。 |
Number.parseFloat() | 转成浮点数 | 将全局方法parseFloat()移植到Number对象上面,行为完全保持不变。 |
Number.isInteger() | 用来判断一个值是否为整数。 | Number.isInteger(25.0) // true |
Number.isSafeInteger() | 用来判断一个整数是否落在 Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER 这两个常量范围之内 | 实际使用这个函数时,需要注意。验证运算结果是否落在安全整数的范围内,不要只验证运算结果,而要同时验证参与运算的每个值。 |
2.扩展的常量
常量 | 说明 | 备注 |
---|---|---|
Number.EPSILON | 极小的常量 | 引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围。我们知道浮点数计算是不精确的。但是如果这个误差能够小于Number.EPSILON,我们就可以认为得到了正确结果。 |
Number.MAX_SAFE_INTEGER / Number.MIN_SAFE_INTEGER | 用来表示安全范围的上下限。 |
六、数组的扩展
ES6为Array原型和数组扩展了一些API。
方法 | 语法 | 说明 | 备注 |
---|---|---|---|
Array.from() | (1) 用于将两类对象转为真正的数组:类似数组的对象和可遍历的对象(包括ES6新增的数据结构Set和Map)。(2) 还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。(3) 第一个参数指定了第二个参数运行的次数。 | 任何有length属性的对象也可转换。 | |
Array.of() | Array.of(n1,n2,n3,…) // =>[n1,n2,n3,…] | 用于将一组值,转换为数组 | Array.of(3, 11, 8) // [3,11,8] |
copyWithin() | Array.prototype.copyWithin(target[, start = 0, end = this.length]) | 在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。 | 会修改当前数组。 |
find() | arr.find((n)=>{return 条件}) | 用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。 | |
findIndex() | arr.findIndex((n)=>{return 条件}) | 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。 | |
fill() | arr.fill(num) | (1) 使用给定值,填充一个数组。(2) 还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。 | 数组中已有的元素,会被全部抹去。 |
entries() | arr.entries() | 用于遍历数组,返回一个遍历器对象,是对键值对的遍历。 | 遍历 |
keys() | arr.keys() | 用于遍历数组,返回一个遍历器对象,是对键名的遍历。 | 遍历 |
values() | arr.values() | 用于遍历数组,返回一个遍历器对象,是对键值的遍历。 | 遍历 |
includes() | arr.includes(查找的元素,num) | 回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。(1) 该方法的第二个参数表示搜索的起始位置,默认为0。(2) 如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度,则会重置为从0开始。 | ES7 |
ES6明确将数组的空位转为undefined。
七、函数的扩展
1.函数参数默认值
避免 y = y || 'World';
这种写法的漏洞(给y复制为false时,直接取默认值“World”)。
可与解构赋值结合使用。
参数默认值的位置只有在尾部时比较方便,不在尾部的话调用时不能省略,必须填写undefined。
length属性的含义是,该函数预期传入的参数个数。指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。length属性的返回值,等于函数的参数个数减去指定了默认值的参数个数。如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。
rest参数中的变量代表一个数组,所以数组特有的方法都可以用于这个变量。
2.扩展运算符
扩展运算符(spread)是三个点(…)。将一个数组转为用逗号分隔的参数序列。该运算符主要用于函数调用。
应用:
- Math.max(…[14, 3, 77]) //数组求最大值
- var arr1 = [0, 1, 2]; //数组合并
var arr2 = [3, 4, 5];
arr1.push(…arr2); - [1, 2, …more] //数组合并
- 如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
- 将字符串转为真正的数组:[…‘hello’] // [ “h”, “e”, “l”, “l”, “o” ]
- 任何Iterator接口的对象,都可以用扩展运算符转为真正的数组。
3.严格模式
从ES5开始,函数内部可以设定为严格模式。
只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
4.name属性
返回该函数的函数名。
如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名。
Function构造函数返回的函数实例,name属性的值为“anonymous”。(new Function).name // “anonymous”
bind返回的函数,name属性值会加上“bound ”前缀。 foo.bind({}).name // “bound foo”
5.箭头函数
var f = v => v;
上面的箭头函数等同于:
var f = function(v) {
return v;
};
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
使用注意点
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。
6.函数绑定运算符::
函数绑定运算符是并排的两个双冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。
foo::bar;
// 等同于
bar.bind(foo);
由于双冒号运算符返回的还是原对象,因此可以采用链式写法。
7.尾调用优化 - ???不理解
尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数。
function f(x){
return g(x);
}
只保留内层函数的调用帧。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。
注意,只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化”。
尾递归函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
8.函数参数的尾逗号
ECMAScript 2017将允许函数的最后一个参数有尾逗号(trailing comma)。
此前,函数定义和调用时,都不允许最后一个参数后面出现逗号。
这样的话,如果以后修改代码,想为函数clownsEverywhere添加第三个参数,就势必要在第二个参数后面添加一个逗号。这对版本管理系统来说,就会显示,添加逗号的那一行也发生了变动。这看上去有点冗余,因此新的语法允许定义和调用时,尾部直接有一个逗号。
function clownsEverywhere(
param1,
param2
) { /* ... */ }
clownsEverywhere(
'foo',
'bar'
);
function clownsEverywhere(
param1,
param2,
) { /* ... */ }
clownsEverywhere(
'foo',
'bar',
);
八、对象的扩展
1.属性的简洁表示法
- ES6允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。
obj={foo};
//等价于
let foo='123';
obj={foo:foo};//obj={foo:'123'};
- 除了属性简写,方法也可以简写。
var o = {
method() {
return "Hello!";
}
};
// 等同于
var o = {
method: function() {
return "Hello!";
}
};
2.属性名表达式
定义对象的属性:
obj.foo = true; // 方法一
obj['foo'] = true; // 方法二
属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
[keyA]: 'valueA',
[keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}
3.Object的API扩展
方法 | 说明 | 备注 |
---|---|---|
Object.is() | 用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致 | 严格比较运算符(===)的NaN不等于自身,以及+0等于-0 |
Object.assign() | 用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。第一个参数是目标对象,后面的参数都是源对象。 | (1) 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。(2) 如果只有一个参数,Object.assign会直接返回该参数。(3) 如果该参数不是对象,则会先转成对象,然后返回。(4) 由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。(5) 实行的是浅拷贝,而不是深拷贝。(6) 可以用来处理数组,但是会把数组视为对象。 |
Object.keys() | 返回对象自身的所有可枚举的属性的键名 | (1) 在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES6中,非对象的参数将被强制转换为一个对象。(2) 尽量不要用for…in循环,而用Object.keys()代替。 |
Object.getOwnPropertyDescriptor(obj,key) | 获取该属性的描述对象。 | 解决Object.assign()无法正确拷贝get属性和set属性的问题。 |
__proto__属性 | 用来读取或设置当前对象的prototype对象。 | 目前所有浏览器(包括IE11)都部署了这个属性。从语义的角度,和从兼容性的角度,都不要使用这个属性。 |
Object.setPrototypeOf() | 用来设置一个对象的prototype对象。 | 是ES6正式推荐的设置原型对象的方法。 |
Object.getPrototypeOf() | 用于读取一个对象的prototype对象。 | |
Object.values() | 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值。 | ES7。如果Object.values方法的参数是一个字符串,会返回各个字符组成的一个数组。 |
Object.entries() | 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。 | 可以将对象转为真正的Map结构。 |
Object.keys() | 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键名。 | |
Object.getOwnPropertySymbols | 返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。 | 由于以 Symbol 值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。 |
4.ES6支持的遍历对象的5种方法
(1)for…in
for…in循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。
(2)Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有Symbol属性。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。
5.对象的扩展运算符
解构赋值
扩展运算符:用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。