ES6
概述
- ESCAScript6.0(简称ES6),是JavaScript语言的下一代标准,在2015年6月正式发布
- 目标:用来编写复杂大型的应用程序,称为企业级的开发语言
ES6编程基础
var
问题:
- ES5只有全局作用域和函数作用域,没有块级作用域
- 在编译时会有一个变量提升的效果,并对提升的变量赋予了默认值undefined
var tmp = 100;
function fn(){
document.write(tmp);
if (false){
var tmp = 10;
}
}
fn();
let命令
用于声明块级作用域的局部变量的关键字
基础用法
let x = 10;
if (true){
let x = 20;
document.write(x);
}
document.write(x);
作用域:与var关键字不同,let声明的变量仅在最接近的一对大括号{}
内有效
不能重复声明
暂时性死区:在变量声明前的这段代码区域,称为暂时性死区
- 暂时性死区中,变量不能使用
- let有提升的效果,但是不像var声明的变量名被初始化为undefined,let提升后没有初始值,所以不能使用
不绑定全局变量
在全局作用域中用let声明的变量不会成为window对象的属性
let x = 10; document.write(window.x);//undefined
const命令
const用于声明一个不可以重新赋值的变量
const x = 10;
x = 100;//报错
const obj = {
age:20
}
obj.age = 30;//不报错
obj = {
age:30
}//报错
解构赋值
用于提取数组或对象中的数据,并赋值给变量
数组解构
let arr = [1,2,3];
const[a,b,c] = arr;
const[a,,c]=arr;
对象解构
let obj = {
name:'tom',
age:20
}
let {name:n,age} = obj;//n指别名
let obj = {
name:'tom',
age:20,
scores:{
math:100,
chinese:90
}
}
let {name,age,scores:{math,chinese}} = obj;
document.write(name+"<br>"+age+"<br>"+math+"<br>"+chinese)
函数参数解构
function greet({name,age}){
return `我的姓名是:${name},我的年龄是:${age}`;
}
let s = greet({name:'tom',age:20});
document.write(s)
函数的扩展——rest参数(剩余参数)
rest参数允许将一个不定数量的参数表示为一个数组,rest参数在函数参数的最后一个位置,前面有一个...
作为前缀
function sum(...arr){
let sum = 0;
for (let n of arr) {
sum += n;
}
return sum;
}
let number = sum(1,2,3);
document.write(number);/
扩展运算符(展开运算符)
定义:用于将一个数组或可迭代对象(如:字符串)展开到由0个或多个参数组成的列表中
数组中使用:
const arr1 = [1,2,3];
const arr2 = [4,5,6,7];
//合并
const arr =[...arr1,...arr2];
document.write(arr.toString());
//克隆
const arr1 = [1,2,3];
const arr = [...arr1];
document.write(arr.toString())
//展开数组作为函数的参数
function sum(x,y,z){
return x+y+z;
}
let sum1 = sum(...nums);
document.write(sum1);
对象中使用:
//合并两个对象
let obj1 = {name:'tom',sex:'男'};
let obj2 = {age:'20'};
let obj = {...obj1,...obj2};
document.write(obj.name+" "+obj.age+" "+obj.sex);
//克隆对象
let obj2 = {...obj1};
document.write(obj2.name+" "+obj2.sex);
增强版的对象字面量
属性名简写
const name = "tom" , age = 20; const obj = {name:name,age:age};//未简写 const obj = {name,age};//简写
计算属性名:使用表达式作为属性名
const propName = 'name'; const obj = { [propName]:'tom' } document.write(obj.name);
简写方法名
//ES5 const obj = { name:'tom', sayHi:function(){ } } //ES6 const obj = { name :'tom', sayHi(){ } }
箭头函数
基础语法
无参数:如果没有参数,也需要使用一对空括号
const sayHi = ()=>{return 'hello'};
单个参数:可以省略括号
const sayHi = name=>{return `hello!${name}`};
多参数:用括号括起来
const sum = (x,y) =>{return x+y}
函数体
简化函数体(单表达式):对于只包含一个表达式的函数体,可以直接返回结果,无需return
const sum = (x,y) => {return x+y} //简化 const sum = (x,y) => x+y;
完整函数体(多条语句):需要使用大括号,并显示使用return
const sum = (x,y)=>{ let result = x + y; return result; }
不具备arguments对象
let sum = (...arr)=>{
//箭头函数没有arguments对象
document.write(arr)
}
sum(1,2,3,4);
this的行为
箭头函数没有自己的this,它会捕获其所在上下文的this值作为自己的this值。这是箭头函数最重要的特点
function test(){
console.log(this)//{name:'tom'}
let t;
/* t = function (){
console.log(this)
}*/
t=()=>{ console.log(this)};//{name:'tom'}
t();
}
let stu ={name:"tom"}
stu.test = test;
stu.test();
模块化
ES6模块的主要思想是必须显示地使用标识符导出模块数据,才能从外部访问模块
导入导出方式一:要求导入的时候使用导出时候的名称
//js/1.js export var x = 100; //demo12.html import {x} from './js/1.js' document.write//模块是异步加载的
默认导出导入
//./3.js export default { name:'tom' }; const x = 100; function sum(num1,num2){ return num1+num2; } export {x,sum};
<!--index.html--> <script type='module'> import obj,{x,sum} from './3.js' console.log(obj.name,x,sum(1,2)); </script>
全部导入
import * as app from './3.js' console.log(app.default.name); console.log(app.x); console.log(app.sum(1,2));
注意:模块内的方法的作用域就是当前模块,不是全局作用域
import {sayHi} from './3.js' //DOMContentLoaded:在html文件被完全加载和解析完成后触发,不等待样式表和图像,子框架的完成 //异步加载的模块会在DOMContentLoaded时间执行前加载完成 document.addEventListener('DOMContentLoaded',function (){ window.sayHi = sayHi; document.querySelector("[value='测试']").addEventListener("click",sayHi); });
面向对象
构造函数
定义:用于创建和初始化一个对象的特殊函数
定义构造函数
function Person(name,age){ this.name=name; this.age=age; }
使用new关键字创建对象
const p = new Person('tom',20)
访问属性
document.write(p.name);
注意:
- 使用大写的字母开始的函数名表示这是一个构造函数
- 使用new关键字调用函数
- this关键字表示在构造函数之内指向新创建的对象
原型(prototype)
定义:JavaScript中的每个对象都有一个与之关联的”原型”对象,从该原型对象继承属性和方法
定义原型对象
Person.prototype.sayHi = function(){ document.write("hi") }
通过原型添加的方法可以被所有实例共享
const p = new Person('tom',20); p.sayHi();//现在p对象内部查找sayHi()方法,如果没有就回到prototype中查找
类
在ES6中,js引入了类的概念,使得面向对象编程更加直观和简单,类在js中实际上是基于原型的继承的语法
定义类
class Person{
constructor(name,age) {
this.name = name;
this.age = age;
}
sayHi(){
console.log("Hi")
}
}
创建实例
const p = new Person('tom',18);
调用方法
p.sayHi();
继承
class Student extends Person{
constructor(name,age,score) {
super(name,age);
this.score = score;
}
}
const stu = new Student('Marry',18,99);
console.log(stu.name,stu.age,stu.score);
stu.sayHi();
静态方法
只能在类上调用,不能通过实例调用
class Person{
constructor(name,age) {
this.name = name;
this.age = age;
}
static sayHi(){
console.log("Hi")
}
}
Person.sayHi();