定义
于2015年发布的, javascript的第六个版本 以及后续版本就是统称为ES6;
Symbol
1.定义变量
es5
-
关键字:
var
-
特点(两个):
-
[1]有变量提升:将所有定义的变量提升到
当前作用域
最顶端-
举例说明:
console.log(a) //undefined var a = 100 console.log(a) //100 var a = 200 console.log(a) //200 // 相当于 var a; console.log(a) //undefined a=100; console.log(a) //100 a=200; console.log(a) //200
-
因此[1]:可以在同一作用域多次定义相同的变量–都提升到当前作用域的最前面,被覆盖;
-
因此[2]:变量可以在声明之前访问(值为undefined)
-
-
[2]没有块级作用域:分支和循环大括号里面声明的变量是
全局
的;-
举例说明
if(true){ var b=10; } console.log(b); //10 // 若是具有块级作用域:块级作用域内部可以访问全局变量,但是全局作用域中不能访问局部变量(局部作用域、块级作用域中定义的变量)
-
-
es6
-
关键字
- 关键字1:
let
- 关键字2:
const
- 关键字1:
-
let 和const共同点
-
没有变量提升:
-
因此[1]变量必须先声明后访问
-
因此[2]同一变量在同一作用域不能重复定义
-
举例说明
console.log(n1);//报错n1 is not defined let n1 = 10; console.log(n1);//10
let a=10 let a=20 console.log(a) // Identifier 'a' has already been declared
-
-
有块级作用域
-
分支和循环大括号里面声明的变量是 ‘局部’ 的,外面不能调用
-
举例说明
if (true) { let n2 = 10; } console.log(n2);//n2 is not defined
-
-
-
let与const的区别
-
let --变量–可以重新赋值;
let a=20; console.log(a);//20 a=10; console.log(a);//10
-
const-常量–不可以重新赋值(只能在定义的同时赋值一次)
const a = 10; console.log(a); a = 20; console.log(a);//Assignment to constant variable.
const a; a = 20; console.log(a);//Assignment to constant variable. //原因是在定义的时候自动赋值为undefined
-
注意:const说常量是作为变量来说的,
-
其实const是不能够修改栈中的数据,若是使用const定义一个引用类型的数据(数组,对象,函数),当我们修改堆中数据时,不会产生错误
-
举例说明
<script> const person = { name: 'chaochao', area: 'china' } person.name = 'niuniu' console.log(person) //{name:'niuniu',area:'china'} </script>
-
总结:使用const定义的值若是简单数据类型,不能够直接修改,若是复杂数据类型,只要不修改其引用,就可以随便修改;
-
-
示例
示例1
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
- 使用 var关键字 定义变量 没有块级作用域;
- 在上述代码中 变量i使用的var关键字定义—>全局变量;
- i在全局范围内有效—>每次循环 i的值发生变化 —> i++;
- 函数内部的i指向的是全局变量i—> 所有函数内部指向的i为
同一个
i!
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
- 使用let关键字 定义的变量 具有块级作用域;
- 在上述代码中 变量i使用的var关键字定义—>局部变量;
- 每一次循环的i其实都是一个新的变量,i仅在本轮循环范围内部有效;
示例2
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
- 在for循环中,设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域!
示例3
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
- 变量的访问遵循就近原则—>当前作用于存在就访问当前作用域中的变量;不存在就访问上一级作用域中的变量;
- 当在if判断中 tmp会判断当作用域中是否存在,发现存在但是在后面
2.解构赋值
解构赋值语法是一种 Javascript 表达式。通过**解构赋值,**可以将 属性/值 从 对象/数组 中取出,赋值给其他变量;
[1]数组
es5-非解构赋值
// 1.将数组中的值1取出,赋值给变量
let arr = [10, 20, 30]
let num1 = arr[1]
let num2 = arr[2]
console.log(num1, num2)// 20,30
let [,num1,num2] = arr
es6-解构赋值
-
语法 :let [变量1,变量2,…变量3] = 数组
- 左侧的[] 作用是告诉浏览器引擎 右侧是一个数组;
- …是剩余模式表示将剩余的元素赋值给最后一个变量(仅能用在最后一个定义的变量上);
-
举例说明
var fo = ["one", "two", "three",'four','five']; var [one, two, ...three] = fo; console.log(one); // "one" console.log(two); // "two" console.log(three); // ["three",'four','five']
// 不想要第二个元素 var foo = ["one", "two", "three",'four','five']; var [one, , ...three] = foo; console.log(one); // "one" console.log(three); // ["three",'four','five']
var foo = []; var [one, two ] = foo; console.log(one); // undefined console.log(two); // undefined
// 为了防止从数组中取出一个值为undefined的对象,可以在表达式左边的数组中为任意对象预设默认值 var foo = []; var [one='one', two='two' ] = foo; console.log(one); // 'one' console.log(two); // 'two'
利用数组解构赋值交换两个变量的值
-
非解构-借助第三个变量进行交换
let a = 10; let b = 20; let c = a; a=b b=c console.log(a,b) // 20,10
-
解构
let a = 10; let b = 20; [a,b] = [b,a] console.log(a,b) // 20,10
[2]对象
es5-非解构赋值
// 取出对象的属性值赋值给对象
let person = {
name: 'chaochao',
area: 'china'
}
// 取出对象的值赋值给变量
let name = person.name
let area = person.area
console.log(name, area) // 'chaochao', 'china'
let {name,area} = person
// 将变量的值赋值给对象
let name = 'chaochao'
let area = 'china'
let person = {
name: name,
area: area
}
console.log(person) //{name:'chaochao',area:'china'}
let person = {
name,
area
}
es6-解构赋值
-
语法1: ({变量1,变量2,…变量3} = obj)
-
左侧的 {} 表示=右侧是一个对象;
-
会将对象中属性名与变量名相同的的属性值赋值给变量;
-
…表示剩余模式(可以放在任意位置),会将没有进行赋值的属性添加在剩余模式的变量中;
-
举例说明
const obj={ a1:1, a2:2, a3:3, a4:4 } const {a1,a3,...a4} = obj console.log(a1,a3,a4) //1,3,{a2:2,a4:4}
-
-
语法2
-
若是想定义某个变量与属性名不同
- const {
属性名
:变量名
} = 对象
- const {
-
举例说明
const obj={ a1:1, a2:2, a3:3, a4:4 } const {a1:theA1, a2, ...item} = obj console.log('结果', theA1, a2,item) // 1,2,{a3:3,a4:4}
-
-
语法3
-
举例说明
let a = 12 const obj = {a,b:13} console.log(obj) // {a:12,b:13}
-
当对象属性名与变量名相同时,在给属性赋值时可以省略;
-
[3]字符串
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
类似数组的对象都有一个length
属性,因此还可以对这个属性解构赋值。
let {length : len} = 'hello';
len // 5
[4]函数
arguments
1.举例说明
function getnum(){
console.log(arguments) // [1,2,3,4,5]
console.log(arguments.filter(item=> item !=2)) // 报错arguments.filter is not a function
}
getnum(1,2,3,4,5)
2.定义:
arguments
对象是所有(非箭头)函数中都可用的局部变量;- arguments 是一个包含所有传递过来的参数的 伪数组;
剩余参数
1.举例说明
function getnum(n1,n2,...rest){
console.log(n1,n2,rest) // 1,2,[3,4,5]
console.log(rest.filter(item=> item !=5))// [23,4]
}
getnum(1,2,3,4,5)
2.定义:
- 剩余参数语法允许我们将一个不定数量的参数表示为一个数组
- 如果函数的最后一个参数以…为前缀,则它将成为一个由剩余参数组成的真数组;
arguments与剩余参数的区别
- [1]剩余参数只包含那些没有对应形参的实参,而
arguments
对象包含了传给函数的所有实参; - [2]arguments是伪数组,本质是对象; rest参数是真数组;
3.新增的数据类型
[1] Symbol数据类型
es6新增了Symbol数据类型
[2]箭头函数
函数的定义形式
[1]普通有名函数
#特点:可以在函数定义之前调用;
function fn1() {}
[2]普通匿名函数
#特点:必须先定义后调用
let fn2=function(){}
(function(){})()
箭头函数
箭头函数只能使用let fn2=function(){}形式
#[1]将关键字function省略=>提前 #[2]为了对称--将()移动至=>左边 #[3]最终为let fn2=()=>{} () => {} #传参 #[1]若是形参只有一个可以将()省略; #[2]若是函数体中只有一句代码,可以省略{} #[3]若是(函数体中只有一句代码)省略{},该语句带return,则将return一起省略;
举例说明
<script>
let res= num => num+1;
console.log(res(1)); //2
</script>
箭头函数的this指向
个人见解:箭头函数没有this指向,其本质是通过作用域链获取上一级的this指向;
-
因此:
- 1.箭头函数的this指向无法修改(使用上下文模式也无法修改箭头函数的tihs指向)
- 2.箭头函数不能通过new关键字调用,因为new关键字可以修改this指向;
- 3.DOM操作不适合使用箭头函数,因为this不会随着点击元素而改变
-
举例说明
<script> let obj = { name: '好开心', eat () { //1.1---eat是普通对象函数,谁调用指向谁---->obj let fn1 = function () { console.log(this) } // 1.2调用fn1---普通函数,谁调用指向谁---window fn1() let fn2 = () => { console.log(this) } // 1.3调用fn2---匿名函数,找上一级的this(eat)---obj fn2() }, // 2.1调用play--箭头函数找上一级(window) play: () => { let fn1 = function () { console.log(this) } // 2.1调用fn1--普通函数window fn1() let fn2 = () => { console.log(this) } //2.2调用fn2--箭头函数找上一级(play)---window fn2() } } obj.eat() //1.调用eat obj.play() //2.调用play </script>
构造函数class
[3]set数据类型
[1]set(集合)数据类型为Es6新增的数据类型(是引用数据类型)
[2]作用:存储一组数据(和数组非常相似,区别是
无法存储重复的元素
)[3]创建set数据:let s1=new Set(数组);
[4]将set类型数据转化为数组
arr=
Array.form(s1)
—该方法是将伪数组转化为数组的arr=[…s1]–使用展开运算符
更多请看传送门
[4]Map数据类型
es6新增了Map数据类型传送门
4.模板字符串
ES5中的字符串
定义:一切以 单引号’’ 或 双引号"" 包起来的都是字符串
特点1:不能够识别变量的值,若是想中间加变量,需要使用+连接符对字符串做拼接;
特点2:不能识别字符串格式,需要使用转义符eg:不能够换行;
ES6中
模板字符串
定义:一切以反引号 包起来的内容
特点:[1]可以识别变量的值
${变量}
;[2]可以识别字符串格式
示例
const name = 'chaochao'
console.log(`Hello ${name}`) // Hello chaochao
-
模板字符串 可以识别变量
const a =1, b=2 console.log('结果', `${a}+${b}=${a+b}`) // 结果 1+2=3
-
模板字符串 可以识别表达式
test(){ return 'aaa' }, const name = 'chaochao' console.log(`这是 ${this.test()}`) // 这是 aaa
-
在模板字符串内 可以调用方法
console.log(`第一行 第二行`) 第一行 第二行
-
在模板字符串内 可以识别字符串格式
5.字符串
[1]新增数组遍历
for of
[2]新增字符串方法
6.数组
[1]新增的数组遍历方法
[2]Array.from方法
Array.from是es6新增的数组方法,用于将伪数组、Set、Map转为真正的数组;
不会改变原数据,返回一个标准数组;
7.新增块级作用域
8.Promise异步操作
es6新增了Promise