ES6语法--简单介绍几点
详细文档: https://es6.ruanyifeng.com/#docs/intro
let 与 const
let
-
不能使用window获取let定义的变量;
-
有全局/块级/函数三种作用域;
-
不会存在变量提升;
-
变量可以更改,但不能重复声明。
<script>
console.log(a) // Cannot access 'a' before initialization 没有变量提升
let a = 30; // let 定义的全局作用域变量,可以在全局/局部使用
// let a = 40; // Identifier 'a' has already been declared let变量不能重复声明
console.log(a) // 30
console.log(window.a) // undefined 全局变量不能用window调用
// let定义的块级作用域变量,只在此块内生效
{
let b=10
console.log(b) // 10
}
console.log(b) // b is not defined
// let定义的函数作用域变量,只在此函数体内生效
function func () {
let c=20
console.log(c)
}
func() // 20
console.log(c) // c is not defined
</script>
ES5中的var (比较)
- 可以用window获取var定义的变量;
- 有 全局/函数两种作用域;
- 有变量提升;
- 可以重复声明。
<script>
// var定义的变量有变量提升,相当于在该作用域的顶部有个 var a;
console.log(a) // undefined 定义了变量没有值。 变量提升
var a = 20; // var 定义的全局作用域变量
var a = 30; // var 变量可以重复声明
console.log(a) // 30
console.log(window.a) // 30
// var没有块级作用域, { }内也相当于全局
{
var b=10
console.log(b) // 10
}
console.log(b) // 10
// var定义的函数作用域变量,只在此函数体内生效
function func () {
var c=20
console.log(c)
}
func() // 20
console.log(c) // c is not defined
</script>
const
- 用来声明常量
- 不能重复声明 或 更改
- 其他特征与let 一致
- 当用const定义对象的时候,即为常量对象,内存空间不能够覆盖,但是可以添加属性
<script>
console.log(PI) // Cannot access 'PI' before initialization 没有变量提升
const PI = 3.14; // let 定义的全局作用域变量,可以在全局/局部使用
PI = 3.14159 // Assignment to constant variable const常量不能更改
const PI = 3.1415926; // Identifier 'PI' has already been declared const常量不能重复声明
console.log(PI) // 3.14
</script>
小练习
分别用 var ,let 定义 i 变量,会输出什么?
<script>
var a = []
for (let i = 0;i < 10;i++) {
a[i] = function () {
console.log(i)
}
}
a[1]();
</script>
<script>
var a = []
for (var i = 0;i < 10;i++) {
a[i] = function () {
console.log(i)
}
}
a[1]();
</script>
分析
// 答案: let定义的i,a[1]()输出 1;var定义的i,a[1]()输出 10;
// 以下为个人分析,不一定正确
// 用var定义,每一次循环 i都在同一个函数作用域内,相当于:
<script>
var a = []
function func () {
var i = 0;
a[i] = function () {
console.log(i)
}
var i = 1
a[i] = function () {
console.log(i)
}
var i = 2
a[i] = function () {
console.log(i)
}
}
func ()
a[1](); // 输出的是最后一个i值
</script>
// 用let定义,因为有块级作用域,每一次循环的i都在一个单独的块级作用域中,相当于:
<script>
var a = []
function func () {
{ let i = 0;
a[i] = function () {
console.log(i)
}}
{ let i = 1
a[i] = function () {
console.log(i)
}}
{
let i = 2
a[i] = function () {
console.log(i)
}}
}
func ()
a[1](); // 输出1
</script>
模板字符串
使用模板字符串可以在字符串内插入变量
用反引号 `` 声明字符串,用 ${变量名} 引入变量
<script>
// 普通定义字符串
let name = '未来';
// 模板字符串
let str = `我叫${name}`;
console.log(str) // 我叫未来
</script>
数据解构
对象解构
解构时,变量名需要和对象中的key值相同,解构对象需要将变量用 { } 括起来。
// 定义一个对象
const info = {name:'yxf',age:'3'};
// 对象解构
let {name,age}=info; // 相当于let {age,name}=info;, 赋值时,变量名与对象中的key相对应,与顺序无关
console.log(name,age) // yxf 3
数组解构
解构数组需要将变量用 [ ] 括起来
// 定义一个数据
const students = ['tom','alex','samda']
// 数组解构
let [s1,s2] = students
console.log(s1,s2) // tom alex
箭头函数
ES5中函数的定义方式:
function func1(x) {
return x;
}
var func2 = function (x) {
return x;
}
ES6中引入箭头函数,书写更简便,还支持定义默认值
// 传入单个参数
let func3 = x => x;
let func4 = (x) => { return x; }
// 传入多个参数,在形参处可直接设定默认值
let func5 = (x,y=9) => { return x+y; }
console.log(func5(x=6)) // 15
this指向问题
<script>
// 对象中es5的函数定义方式定义的函数this指向调用者,即 person1.GetName() 的person1
let person1 = {
name: '杨稀饭',
age: 3,
GetName: function (){
console.log(this) // person1 这个对象
console.log(this.name) // person1.name
}
}
person1.GetName()
// 对象中箭头函数的this指向它的调用者所在的上下文(即此处person2的父级对象window)
let person2 = {
name: '杨稀饭',
age: 3,
GetName: () => {
console.log(this) // window
console.log(this.name) // 获取的是window.name
}
}
person2.GetName()
// 单体模式下函数的this与上面第一种情况一样,指向它的调用者
let person3 = {
name: '杨稀饭',
age: 3,
// 单体模式
GetName () {
console.log(this) // person3 这个对象
console.log(this.name) // 获取的是person3.name
}
}
person3.GetName()
</script>
类
ES5中的类的定义与实例化
<script>
// 定义类 --构造函数
var Person1 = function (username,age){
this.username = username
this.age = age;
}
// 定义类中的方法
Person1.prototype.showInfo = function (){
console.log(this.username,this.age)
}
let p1=new Person1('yxf',3);
p1.showInfo()
</script>
ES6中类的定义,继承与实例化,有构造方法
<script>
class Father {
// constructor 构造方法,类似于__init__
constructor (username,age,account=100) {
this.username = username;
this.age = age;
this.account = account;
}
showInfo () {
console.log(this.username,this.age,this.account)
}
}
// extends Father 声明父类Father
class Son extends Father {
constructor (username,age) {
// 继承父类的索引属性与方法
super();
this.username = username;
this.age = age;
}
}
let F1 = new Father('欢爸爸',66,120)
F1.showInfo() // 欢爸爸 66 120
let S1 = new Son('饭儿子',3)
S1.showInfo() // 饭儿子 3 100 (继承了父类中默认account值)
</script>