1.let,const,var的区别:
(1)var 声明的变量不受作用域的限制,而let声明的变量则有严格的作用域
在代码块中声明两个变量a,b,在代码块外访问
{
var a=1;
let b=2;
}
console.log(a);
console.log(b);
结果:var声明的变量可以访问,而let声明的变量会报错
(2) var可以重复多次声明用一个变量,而let只能声明一次,否则编译报错
var m=1;
var m=2;
let n=1;
let n=2;
结果:let会编译报错
(3)var 会变量提升,let不存在变量提升
分别在var 与let声明变量之前访问该变量
console.log(m);
var m=1;
console.log(n);
let n=2;
结果:var 可以正常访问,let则提示变量未定义
(4)const声明的变量为只读,不允许修改
const a=1;
a=3;
结果:控制台报错
2.解构表达式
(1)数组解构
let arr =[1,2,3];
let a = arr[0];
let b = arr[1];
let c = arr[2];
console.log("原来的写法:"+a,b,c);
/
let [a1,b1,c1]=arr
console.log("解构表达式:"+a1,b1,c1);
结果:
(2) 对象解构
const person={
name :"tom",
age :18,
hobby:["java","python"]
}
// 原来的写法
// const name = person.name;
// const age = person.age;
// const hobby = person.hobby;
//解构表达式写法
const {name,age,hobby}= person
console.log(name,age,hobby);
结果:
解构表达式取对象属性时,更改属性变量名:
const person={
name :"tom",
age :18,
hobby:["java","python"]
}
//解构表达式更改属性变量名写法
const {name:xingming,age:nianling,hobby:aihao}= person
console.log(xingming,nianling,aihao);
结果:
3.字符串扩展功能
(1)字符串扩展api
const str ="hello.vue";
// 返回boolean类型,表示是否找找到参数字符串
console.log(str.includes("e"));
console.log(str.includes("hello"));
console.log(str.includes("nihao"));
// 返回boolean类型,表示源字符串是否以参数字符串为开头
console.log(str.startsWith("hello"));
console.log(str.startsWith("apple"));
// 返回boolean类型,表示源字符串是否以参数字符串为结束
console.log(str.endsWith(".vue"));
console.log(str.endsWith(".java"));
结果:
(2)字符串模板
// 原始定义方式
const str = "<div> <span> hello </span> </div>";
// 模板字符串定义方式(保留了结构)
const s = `
<div>
<span>
hello
</span>
</div>
`
console.log(str);
console.log(s);
结果:
(3) 字符串中插入变量和表达式
// 字符串中插入变量
const name = "tom";
const age =18;
const info = `我是${name},今年${age}岁`;
console.log(info);
结果:
// 字符串中插入表达式
const name = "tom";
const age =18;
const info = `我是${name+"父亲"},今年${age+24}岁`;
console.log(info);
结果:
// 字符串中引用方法
const name = "tom";
const age =18;
function say(){
return "tom很优秀";
}
const info = `我是${name+"父亲"},
今年${age+24}岁,我想说:${say()}`;
console.log(info);
结果:
4.函数优化
(1) 函数参数可设置默认值
function add(a,b){
// 若b没有传值的话,b的默认值为1
b=b || 1;
return a+b;
}
// ES6可以在函数定义的时候,给函数设置一个默认值
// 若b没有传值的话,b的默认值为1
function add2(a,b=1){
return a+b;
}
console.log(add(10));
console.log(add2(10));
结果:
(2) 不定参数
function f(...values){
console.log("参数列表长度:"+values.length);
}
f(1,2,3);
f(1,2,3,4,5,6);
结果:
(3) 箭头函数
箭头函数简化函数定义
// ES6之前函数的定义方式
// 多参函数
let m = function (a,b){
console.log(a,b);
}
// 单参函数
let n= function(a){
console.log(a);
}
// ES6箭头函数的定义方式
let m1 = (a,b) => console.log(a,b);
let n1= a=>console.log(a);
// 调用测试
m("hello","word");
n("javascript");
m1("hello","word");
n1("javascript");
结果:
箭头函数取对象属性
const person = {
name: "tom",
age: 18,
hobby: ["java", "python"]
}
// 原始方法
function hello(person) {
console.log(person.name);
}
// 普通箭头函数
let hello2 = (person) => console.log(person.name);
// 解构箭头函数
let hello3 = ({
name
}) => console.log(name);
hello(person);
hello2(person);
hello3(person);
结果:注意第三种解构对象的写法,可以直接写属性
5.对象优化
ES6为对象提供了一些新的API
(1)对象转换成key,value形式
const person = {
name: "tom",
age: 18,
hobby: ["java", "python"]
}
// 获取对象全部key
console.log(Object.keys(person));
// 获取对象全部value
console.log(Object.values(person));
// 获取对象全部key,value
console.log(Object.entries(person));
结果:
(2) 对象属性合并
const person = {
name: "tom",
age: 18,
hobby: ["java", "python"]
}
const info = {
job: "engineer",
salary: "18k",
detail: ["dev", "test"]
}
// 合并person对象与info对象的属性
Object.assign(person, info);
console.log(person);
结果:
(3) 声明对象简写
const name = "jack";
age = 15;
// ES6之前声明对象的方式
const person1 = {
name: name,
age: age
}
// ES6后属性名与变量名相同时可以简写
const person2 = {
name,
age
}
console.log(person1);
console.log(person2);
结果:
(4) 对象内箭头函数声明方法注意事项
const person = {
name: "tom",
age: 18,
hobby: ["java", "python"],
// 对象中声明方法普通方式
eat: function(food) {
console.log(`${this.name}吃${food}`)
},
// 对象中用箭头函数声明方法,使用this.属性,无法获取对象属性
eat2: (food) => console.log(`${this.name}吃${food}`),
// 对象中用箭头函数声明方法,应该用对象名.属性来获取对象
eat3: (food) => console.log(`${person.name}吃${food}`)
}
person.eat("苹果");
person.eat2("香蕉");
person.eat3("香蕉");
结果:
(5) 对象深拷贝与属性合并
const name = {
name: "jack"
};
const age = {
age: 18
};
// 属性合并
const person = {
...name,
...age
}
// 对象深拷贝
const person2 = {
...person
}
// 原对象已经存在name属性的时候,
// 进行深拷贝后会覆盖原来的属性值
let person3 = {
name: "张三"
}
person3 = {
...name,
...age
}
console.log(person);
console.log(person2);
console.log(person3);
结果:
6.Map()与reduce()的用法
(1)map()用法,类似于java的lamda表达式处理数组对象
//将arr数组中的全部元素都乘2,并返回处理后的数组
const arr = [1, 20, 13, -10, 3];
const arr2 = arr.map(item => item * 2);
console.log(arr2);
(2)reduce()用法,为数组每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素
arr.reduce(callback,[initialValue])
callback 上一次调用后返回的值
initialValue 从该初始值开始依次执行回调,如果不设置该初始值,则从数组中的第一个元素开始依次执行回调
const arr = [1, 20, 13, -10, 3];
arr.reduce((a, b) => {
console.log("当前要处理的元素", b);
console.log("上次回调后的元素", a);
return a + b;
})
结果:
(3)reduce()函数赋初始值
const arr = [1, 20, 13, -10, 3];
arr.reduce((a, b) => {
console.log("当前要处理的元素", b);
console.log("上次回调后的元素", a);
return a + b;
}, 100)
结果:
7.promise then异步编排
使用异步调用方式来依次获取用户信息,课程信息,分数信息,后两次请求均依赖上次请求的结果。这里用三个json文件来模拟请求过程:
// 原始ajax异步请求写法
// 模拟一个异步查询的流程:
// 1. 获取当前用户信息
// 2. 根据用户信息查询课程信息
// 3. 根据课程信息查询课程分数
$.ajax({
url: `./student_${10}.json`,
success(data) {
console.log("查询文件", data);
$.ajax({
url: `./course_${data.id}.json`,
success(data) {
console.log("查询文件", data);
$.ajax({
url: `./score_${data.id}.json`,
success(data) {
console.log("查询文件", data);
},
error() {}
})
},
error() {}
})
},
error() {}
})
结果:
使用promise then异步编排:
// 使用promise,then进行异步编排操作,优化了嵌套写法,代码更直观,类似于java的责任链模式
// 将每次异步请求后回调的结果封装成一个promise对象来管理
// 其中resolve参数为执行成功后的回调函数,reject为执行失败后的回调函数
// 使用then()函数,来编排异步调用的顺序
let p1 = new Promise((resolve, reject) => {
$.ajax({
url: `./student_${10}.json`,
success(data) {
console.log("查询文件", data);
resolve(data);
},
error(err) {
reject(err);
}
})
})
let p2 = p1.then((data) => {
return new Promise((resolve, reject) => {
$.ajax({
url: `./course_${data.id}.json`,
success(data) {
console.log("查询文件", data);
resolve(data);
},
error(err) {
reject(err);
}
})
})
})
let p3 = p2.then((data) => {
return new Promise((resolve, reject) => {
$.ajax({
url: `./score_${data.id}.json`,
success(data) {
console.log("查询文件", data);
resolve(data);
},
error(err) {
reject(err);
}
})
})
})
结果:
8.模块化使用
模块化就是将代码拆分,方便功能上的复用,类似于java中的import导包。
js中没有导包的概念,它的处理方式是模块化。
导出几个方法和对象:
add.js:
// 直接导出方法
export const add = (a, b) => retun(a + b)
hello.js
// 默认导出一个匿名对象,可在导入该模块的时候,随意命名该对象
export default {
msg: "hello"
}
export const substrat = (a, b) => {
return a - b;
}
person.js
// 导出对象和一些变量
const name = "tom";
const age = 16;
const person = {
name,
age
}
// 导出多个
export { name, age, person }
在main.js中导入模块,来使用:
// 导入方法
import { add } from "./add.js";
// 多模块导入
import { name, age, person } from "./person.js";
// 匿名对象导入,可以随意命名
import { abc } from "./hello.js";
let sum = add(1, 2);
console.log(sum);
console.log(person)
console.log(name);
console.log(age);
console.log(abc);