变量定义的新方式:let/ const
let 特性:
- 不允许重复声明
- 没有变量提升(预解析)
- 块级作用域(一对
{} 包括的区域称为一个代码块,let 声明的变量只在该代码块起作用)
例子1 :简单的打印数据
使用 var:
1 2 3
| for(var i = 0; i<10 ; i++ ){ setTimeout(()=>console.log(i)) }
|
使用 let:
1 2 3
| for(let i = 0; i<10 ; i++ ){ setTimeout(()=>console.log(i)) }
|
之前我们要实现这样的打印,必须使用闭包:
1 2 3 4 5
| for(var i = 0; i<10;i++){ (function(j){ setTimeout(()=>console.log(j)) })(i) }
|
例子二:在网页中常常会有切换 tab ,展示对应的信息的需求,我们使用 var 来处理时,常常使用的自定义属性,来保存点击的索引。btns[i].index=i。用于找到对应的元素。:
html模板:
1 2 3 4 5 6 7 8 9 10 11
| <style type="text/css"> div{display:none} .show{display:block;} .active{background:red;} </style> <button class="active">1</button> <button>2</button> <button>3</button> <div class="show">11111</div> <div >22223</div> <div >33333</div>
|
js:
1 2 3 4 5 6 7 8 9 10 11 12 13
| var btns = document.querySelectorAll('button') var divs = document.querySelectorAll('div') for (var i=0 ;i<btns.length;i++){ btns[i].index=i btns[i].onclick=function(){ for(var j=0 ;j<btns.length;j++){ btns[j].className='' divs[j].className='' } this.className='active' divs[this.index].className='show' } }
|
使用 let:
1 2 3 4 5 6 7 8 9 10 11 12 13
| var btns = document.querySelectorAll('button') var divs = document.querySelectorAll('div') for (let i=0 ;i<btns.length;i++){ btns[i].onclick=function(){ for(let j=0 ;j<btns.length;j++){ btns[j].className='' divs[j].className='' } this.className='active' divs[i].className='show' } }
|
const 除了具备上述 let 的特性外,还有自己的一个特性:定义之后的值,是固定不变不能被修改的。
值得注意的是下面这两种情况是不会报错的:
1 2 3 4 5 6 7 8 9
| { const a = {value:1} a.value = 2 console.log(a)
const b = [1,2,3] b.push(4) console.log(b) }
|
解构赋值
ES6 允许按照一定的模式,从数组和对象中提取值,这样就称为解构
数组:按照对应的顺序解构
1 2 3 4 5 6 7 8 9 10 11 12
| { var arr = [[1,2,3],[4,5,6],[7,8,9]] var [a,b,c] = arr var x = 1; var y = 2; [y,x] = [x,y] console.log(x,y) }
|
对象按照对应的名称一一对应进行解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { var obj={ get:function(){ return 'get' }, value:1, data:[1,2,3], str:'string' } var {str,get,data} = obj console.log(str) console.log(get()) console.log(data) }
|
模板字符串
模板字符串 是增强版的字符串,使用反引号(```)作为标识 。可以当做普通字符串使用,也可以用来定义多行字符串(会保留换行)。或者在字符串中嵌入变量。
在模板字符串,需要引用变量使用 ${变量名} 的形式。在 {}可以进行运算,也可以引用对象属性。
1 2 3 4 5 6
| { var name = 'xiaoming' var age = 19 var str = `my name is ${name} ,my age is ${age}` console.log(str) }
|
扩展
Array.from(arrayLike[, mapFn[, thisArg]])
arrayLike : 想要转换成真实数组的类数组对象或可遍历对象。
mapFn : 可选参数,如果指定了该参数,则最后生成的数组会经过该函数的加工处理后再返回。
thisArg : 可选参数,执行 mapFn 函数时 this 的值。方法用于将两类对象转为真正的数组:类似数组的对象和可遍历的对象(包括 ES6 新增的数据结构 Set 和 Map )
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { let ps = document.querySelectorAll('p'); Array.from(ps); Array.from(new Set(["foo", window])); Array.from([1, 2, 3], x => x + x); (function () { var args = Array.from(arguments); return args; })(1, 2, 3); }
|
而在这之前,我们要转类数组对象,只能用这样的形式: [].slice.call(ps)
当然或许你根本不需要转,因为我们有 for of 了,只要有遍历接口的类型,它就可以进行遍历
(Set,String,Array,NodeList等等)
1 2 3 4 5 6 7 8 9 10 11
| { let ps = document.querySelectorAll('p'); for (let v of ps){ console.log(v) } for (let [i,item] of ps.entries()){ console.log(i,item) } }
|
Object.assign():拷贝源对象自身的可枚举的属性到目标对象身上
1 2 3 4 5
| { var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); }
|
值得注意的是, Object.assign()执行的是浅拷贝。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。
1 2 3 4 5 6 7
| { let a = { b: {c:4} , d: { e: {f:1}} } let g = Object.assign({},a) g.d.e = 32 console.log(g) console.log(a) }
|
如果你需要的不是合并,而只是普通json对象的复制,建议使用 JSON.parse(JSON.stringify(a)),这样不会有上面的副作用产生。
函数参数默认值。定义默认值得参数必须是尾参数,因为函数形参定义默认值后该参数可以被忽略
1 2 3 4 5 6
| { function fn(a,b=2){ return {a,b} } console.info(fn(1)) }
|
rest参数:用于获取获取函数的多余参数。与参数默认值一样,必须为尾参数
1 2 3 4 5 6
| { function foo(a,b,...args){ console.info(args) } foo(1,2,3,4,5,6) }
|
扩展运算符...:它好比 rest 参数的逆运算。可以将一个数组转为用逗号分隔的参数序列。
1 2 3 4 5 6 7 8 9 10 11 12
| { var arr = [1,2,3,4,5] console.info(Math.max.apply(null,arr)) console.info(Math.max(...arr)) console.info(Math.max(1,2,3,4,5))
var str = 'string' var arr = [...str,4,5]
}
|
箭头函数 Arrow Functions:箭头函数并不是用来替代现有函数而出现的,并且也无法替代。它是用来作为回调函数使用的,主要是为了简化回调函数的写法。
主要有三个特性:
- 箭头函数自身没有
this 。函数内的 this 指向箭头函数 定义时所在的对象 ,而不是使用时所在的对象。
- 箭头函数内部,不存在
arguments 对象
- 不可以当作构造函数,不可以使用
new 指令。
简单用法,简化回调:
1 2 3 4 5 6 7
| { var arr = [7,8,9,10] arr.sort() arr.sort(function(a,b){return a-b}) arr.sort((a,b)=> a - b ) }
|
没有 arguments
1 2 3 4 5 6 7 8 9
| { var foo = (a,b,c)=>{ console.log(a,b,c) console.log(arguments) }; foo(1,2,3) }
|
不要在对象的方法中使用箭头函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| { window.name='window'; var obj = { name:'obj', getName: function(){ console.log(this.name) } } obj.getName() var getName = obj.getName getName() var obj = { name:'obj', getName: () =>{ console.log(this.name) } } obj.getName()
}
|