ES6
ES的全称是ECMAScript ,它是由ECMA国际标准化组织制定的一项脚本语言的标准化规范。
ES6实际上是一个泛指,泛指ES2015及后续的版本。
为什么使用ES6
变量提升特性增加了程序运行时的不可预测性
语法过于松散。实现相同的功能,不同的人可能会写出不同的代码
关键字
let
ES6中新增的用于声明变量的关键字。
特点:
- let声明的变量只在所处于的块级作用域中(也就是大括号里)有效
- 不存在变量提升
<script>
//let关键字就是用来声明变量的
//1、使用let关键字声明的变量具有块级作用域
// let a = 10
// console.log(a)
/*if (true){
let b = 20
console.log(b)
if (true){
let c = 30
}
console.log(c) //c is not defined c只在那个大括号里有用
}
console.log(b)*/
//2、在一个大括号里,使用let关键字声明的变量才具有块级作用域。使用var声明的变量不具备块级作用域特性。
/*if (true){
let num = 100
var abc = 200
}
console.log(abc) //200
console.log(num) //num is not defined*/
//3、防止循环变量变成全局变量
for (let i = 0;i<2;i++){
}
console.log(i) //用let声明 :i is not defined
// 4、使用let关键字声明的变量没有变量提升
/*console.log(a) //报错,在es6中,用let生命的变量只能先声明再使用
let a = 100*/
// 5、使用let关键字声明的变量具有暂时性死区特性
var num = 10
if (true){
console.log(num) //报错
//在块级作用域中用let声明变量,这个变量就会和这个块级区域整体进行绑定
//也就是在当前作用域中使用num和外部的num是没有关系的,所以会报错,因为输出语句写在声明变量之前
let num = 20
}
</script>
经典面试题
<script type="text/javascript">
let arr = [];
//此题的关键点在于每次循环都会产生一个块级作用域。每个块级作用域中的变量都是不同的,
// 函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的值.
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
/*var arr = [];
//此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的值。
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();*/
</script>
const
作用:声明常量,常量就是值(内存地址)不能变化的量。
特点:
- 具有块级作用域
- 声明常量时必须赋值
- 常量赋值后,值不能修改
<script type="text/javascript">
/*// 使用const关键字声明的常量具有块级作用域
if (true) {
const a = 10;
if (true) {
const a = 20;
console.log(a); //20
}
console.log(a); //10
}
console.log(a);//报错*/
// 使用const关键字声明的常量必须赋初始值
// const PI = 3.14;
// 常量声明后值不可更改
const PI = 3.14;
// PI = 100; //报错 1、基本数据类型值不可更改
const ary = [100, 200];
ary[0] = 123;
console.log(ary); //[123, 200] 2、复杂数据类型数据结构内部的值可以更改,但数据值本身不能更改
ary = [1, 2]
console.log(ary) //报错 直接等于数组相当于更改了它的内存地址,不能直接赋值
</script>
let、const、var 的区别
1.使用var声明的变量,其作用域为该语句所在的函数内。且存在变量提升现象。
⒉使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
3.使用const声明的是常量,在后面出现的代码中不能再修改该常量的值。
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |
解构赋值
**解构:**分解数据结构
**赋值:**为变量赋值
ES6中允许从数组中提取值,按照对应位置,对变量赋值。对象也可以实现解构。
按照一定模式,从数组中或对象中提取值。将提取出来的值赋值给另外的变量。
数组解构
如果解构不成功,变量的值是undefined
<script>
//数组解构允许我们按照一一对应的关系从数组中提取值,然后将值赋值给变量
//如果数量不够一一对应,没有对应的值,则输出undefined
let arr = [1,2,3]
//let后的中括号[]不代表数组,代表解构,从数组中提取值,括号里可以直接写变量
let [a,b,c,d,e] = arr //把数组解构赋值给中括号里的变量
console.log(a)
console.log(b)
console.log(c)
console.log(d) //undefined
console.log(e) //undefined
</script>
对象解构
实际是属性匹配,匹配成功的话将属性的值赋值给变量
<script>
//对象解构允许我们使用变量的名字匹配对象的属性,匹配成功将对象属性的值赋值给变量
let person = {name:'lisi',age:30,sex:'男'}
//1、用大括号里的变量名字匹配对象的属性,匹配成功的话将属性的值赋值给变量
let {name,age,sex} = person
console.log(name)
console.log(age)
console.log(sex)
//2、用name属性匹配person中的name属性,匹配完成后将person中name的值赋值给myName变量
let {name:myName,age:myAge} = person
console.log(myName)
console.log(myAge)
</script>
箭头函数
ES6中新增的定义函数的方式
定义:(形参)=> { 函数体 }
**调用:**箭头函数通常被赋值给一个变量,变量的名字就是箭头函数名字,通过变量名字调用函数
特点:
- 函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
- 如果形参只有一个,可以省略小括号
- 箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this。
- this是静态的,不能改变this指向,this始终指向函数声明时所在作用域下的 this 的值
- 不能作为构造函数实例化对象
- 不能使用arguments 变量
<script>
//箭头函数是用来简化函数定义语法的
const fn = ()=>{
console.log(123)
}
fn() //123
// 1、函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
const sum = (num1,num2)=> num1 + num2
// 相当于底下这个代码
/*const sum = (num1,num2)=> {
return num1 + num2
}*/
console.log(sum(10,20))
// 2、如果形参只有一个,可以省略小括号
/*function fn1 (v) {
return v
}*/
// 可以写成底下的箭头函数
/*const fn1 = (v) => {
return v
}*/
const fn1 = v => v
console.log(fn1(3))
// 3、箭头函数不绑定this关键字,箭头函数中的this,指向的是箭头函数定义位置的上下文this。
function fn2(){
console.log(this) //obj
return () => {
console.log(this) //obj
}
}
const obj = {name:'zhangsna'}
//使用resFn接收fn2的返回结果,也就是箭头函数的this
//call 更改fn2的this指向,更改为指向obj
const resFn = fn2.call(obj)
resFn()
</script>
面试题
<script>
var age = 100
var obj = {
age:20,
// obj对象不能产生作用域,say方法其实是定义在全局作用域下,故this指向的是window
say:()=>{
alert(this.age) //100
},
say1:function (){
console.log(this.age) //20
}
}
obj.say()
obj.say1()
</script>
剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组
<script>
//...args代表接收所有的形参
const sum = (...args)=>{
let total = 0
args.forEach(item => {
total += item
})
return total
}
console.log(sum(10,20))
console.log(sum(10,20,30))
</script>
<script>
//剩余参数和解构搭配使用
let arr = ['zhangsan1','lisi','wangwu']
let [s1,...s2] = arr
console.log(s1) //zhangsan1
console.log(s2) //['lisi', 'wangwu']
</script>
内置对象扩展
Array数组的扩展方法
1、扩展运算符(展开语法)…
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<script>
//1、扩展运算符就是把数组拆分为参数序列(逗号分隔)
let arr = ['a','b','c']
// ...arr //a,b,c
console.log(...arr) //a b c
console.log('a','b','c') //a b c
// 2、扩展运算符可以应用于合并数组
// 合并arr1,arr2
let arr1 = [1,2,3]
let arr2 = [4,5,6]
//方法1
let arr3 = [...arr1,...arr2]
let con = arr1.concat(arr2)
console.log(con)
console.log(arr3) //[1, 2, 3, 4, 5, 6]
// 方法2
arr1.push(...arr2)
console.log(arr1) //[1, 2, 3, 4, 5, 6]
// 3、将类数组或可遍历对象转换为真正的数组
var divs = document.getElementsByTagName('div')
console.log(divs) //伪数组
let arr4 = [...divs]
console.log(arr4) //真数组 这样就可以使用数组的方法 比如push
arr4.push('a')
console.log(arr4) //[div, div, div, div, div, 'a']
// 4、数组的克隆
let arra = ['a','d','c']
let arrb = [...arra]
console.log(arrb) //浅拷贝
</script>
2、构造函数方法:Array.from()
将类数组或可遍历对象转换为真正的数组
Array.from(伪数组) 返回值就是转换好的真数组
<script>
var arrayLike = {
'0':'张三',
'1':'李四',
'2':'王五',
'length':3
}
console.log(arrayLike)
var arr = Array.from(arrayLike)
console.log(arr) //['张三', '李四', '王五']
var arrayLike1 = {
'0':'1',
'1':'2',
'length':2
}
//方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
//相当于把arrlike2转换为真数组,并给每一项都做一个操作:乘2
var arr1 = Array.from(arrayLike1,(item)=>{
return item*2
})
console.log(arr1) //[2, 4]
</script>
3、实例方法:find()
参数是一个函数,用于找出第一个符合条件的数组成员,如果没有找到返回undefined
<script>
var arr = [{
id:1,
name:'张三'
},{
id:2,
name:'李四'
}]
//查找arr中符合id=2的数据
let target = arr.find(item=> item.id === 2)
console.log(target)
</script>
4、实例方法:findIndex()
用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
<script>
let ary = [10, 20, 50];
//findIndex用于找出第一个符合条件的数组成员的位置,返回index,如果没有找到返回-1
let index = ary.findIndex(item => item > 15);
console.log(index) //1 表示符合条件>15的数组成员的位置是1
</script>
5、实例方法:includes()
表示某个数组是否包含给定的值,返回布尔值。
<script>
//表示某个数组是否包含给定的值,返回布尔值。
let arr = ['a','b','c']
let result = arr.includes('a')
console.log(result) //true
result = arr.includes('e')
console.log(result) //false
</script>
String字符串的扩展方法
1、模板字符串(反引号定义)
ES6新增的创建字符串的方式,使用反引号定义。
特点:
- 模板字符串中可以解析变量
- 模板字符串可以换行
- 在模板字符串中可以调用函数
<script>
//1、模板字符串中可以解析变量
//用${}可以解析字符串,拼接起来,不用用引号加号将字符串拼接
let name = `张三`
let sayHello = `hello,我的名字是${name}`
// console.log(name)
console.log(sayHello) //hello,我的名字是张三
// 2、模板字符串可以换行
let result = {
name:'zhangsan',
age:20
};
let html = `<div>
<span>${result.name}</span>
<span>${result.age}</span>
</div>`
console.log(html) //有换行效果 且获取到了属性值 zhangsna与20
// 3、在模板字符串中可以调用函数
const fn = ()=>{
return '我是fn函数'
}
let str = `我是模板字符串 ${fn()}`
console.log(str) //我是模板字符串 我是fn函数 (调用了函数,显示函数的返回值)
</script>
2、实例方法:starsWith()和endsWith()
startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值
<script>
let str= 'hello nihao woshirenlei!!!'
let r1 = str.startsWith('hello') //true
let r2 = str.endsWith('!') //true
console.log(r1) //true
console.log(r2) //true
</script>
3、实例方法:repeat()
repeat方法表示将原字符串重复n次。返回一个新字符串。
<script>
//repeat方法表示将原字符串重复n次。返回一个新字符串。
console.log('y'.repeat(5)) //yyyyy
let str = 'hello'
console.log(str.repeat(6)) //hellohellohellohellohellohello
console.log(str) //hello 原字符串不受影响 返回的是一个新字符串
</script>
Set数据结构
ES6提供了新的数据结构Set。它类似于数组。但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成Set 数据结构。
Set函数可以接受一个数组作为参数,用来初始化
实例方法:
add(value):添加某个值,返回Set结构本身
delete(value):删除某个值,返回一个布尔值。表示删除是否成功
has(value):返回一个布尔值,表示该值是否为Set的成员
clear():清除所有成员,没有返回值