目录
let和const命令
let命令
基本用法:
let用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。
特点:
- 块级作用域:只在let命令所在的代码块内有效
- 不存在变量提升:声明之前使用变量会导致程序报错
- 暂存性死区:es6明确规定,如果区块中存在
let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。在let或者const声明变量之前,该变量是不可以用的,在语法上称之为“暂存性死区”
例如:
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
- 4. 不允许重复声明 :在同一个作用域内用let修饰的变量不可以声明多次
思考:
为什么需要引入块级作用域
1.解决内层变量可能会覆盖外层变量
例如:以下代码,打印部分会输出undefined,是因为函数内部重新声明了a变量,变量提升,导致a被重新声明,没有执行赋值操作,打印结果变为undefined
var a = '123'
function f(){
console.log(a)
if(false){
var a = '456'
}
}
f() //undefined
2.防止用来计数的变量泄露为全局变量
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
const命令
基本用法:
一般来说const常用来声明一个常量,一旦声明,常量的值就不能改变。
特点:
- 块级作用域
- 只声明不赋值会报错,因为const 修饰的变量不能重新赋值
- 不会进行变量提升
- 不可重复赋值
- const 实际保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,
const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。 例如:const a = []; a.push('Hello'); // 可执行 a.length = 0; // 可执行 a = ['Dave']; // 报错
上面代码中,a是一个数组,数组本身是可以写的,可以删除添加数组中的元素,但如果将另一个值赋值给数组,就会报错
-
如果真的想冻结对象和数组,可以使用Object.freeze()方法,除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。
var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, i) => { if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); } }); };
变量的解构赋值
数组的结构赋值
基本用法:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
使用:
- 基本用法
let a = 1 let b = 2 let c = 3 可以写成 let [a, b, c] = [1, 2, 3]
- 默认值:解构赋值允许指定默认值。
let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
注意,ES6 内部使用严格相等运算符(
===
),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined
,默认值才会生效。let [x = 1] = [undefined]; x // 1 let [x = 1] = [null]; x // null
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
String新增方法
startsWith()
返回:布尔值。表示参数字符串是否在目标字符串头部
参数1:参数字符串
参数2:开始查找的位置
let str = 'abcdef'
str.startsWith('')
true
str.startsWith('abc')
true
str.startsWith('abc',1)
false
str.startsWith('abc',0)
true
endsWith()
返回:布尔值。表示参数字符串是否在目标字符串尾部
参数1:参数字符串
参数2:开始查找位置,但是从当前位置往前查,也就是从1到第n个位置
var str = 'abcdef'
str.endsWith('f')
true
str.endsWith('d',3)
false
includes()
返回:布尔值。标识参数字符串是否在目标字符串中存在
参数1:参数字符串
参数2:开始查找位置
str.includes('k')
false
str.includes('k')
false
str.includes('b',2)
false
str.includes('b',1)
true
str.includes('a',1)
false
注意:以上三个方法都会区分大小写
Number新增的方法
Number.isFinite()
返回:布尔,检测参数值是否是有限的数值,如果是无限的返回false,有限的返回true,如果是非数字都返回false
Number.isFinite(1.0002)
true
Number.isFinite(NaN)
false
Number.isFinite('123')
false
Number.isFinite(Infinity)
false
Number.isNaN()
返回:布尔,用来检测一个参数值是否为NaN,如果不是NaN一律返回false,否则返回true
Number.isNaN(1)
false
Number.isNaN(NaN)
true
Number.isNaN('1')
false
Number.isNaN('123')
false
Number.isNaN('abc')
false
Number.isNaN('NaN')
false
isNaN(NaN)
true
isNaN('NaN')
true
isNaN('12')
false
isNaN('abc')
true
isNaN()与isFinite()与Number方法的区别,就是全局isNaN()与isFinite()会将Number转换成数值类型,而Number上的这两个方法则不会转换。对于非数值类型的参数,直接返回false。
Array上的方法
find()
返回:第一个符合条件的成员,如果没有返回undefined
参数:是一个回调函数,所有成员依次执行回调函数
var arr = [1,2,-1,-2,3]
arr.find(n => n < 0)
-1
findIndex()
返回:第一个符合条件的成员的索引,如果所有成员都不符合条件则返回-1
参数:是一个回调函数,所有成员依次执行回调函数
arr.findIndex(n => n < 0)
2