目录
1.三种定义关键字
var
1.有预解析
2.可以重复定义变量
3.可以修改值
4.除了在函数内部定义的是局部作用域其他的都是全局作用域
let
1.不能预解析
2.在同一块级作用域不能重复定义相同变量名
3.可以修改值
4.有自己的块级作用域 { }
5.只能在{}里面才可以使用,外面访问不到
const
1.定义的是常量
2.不能在同一块级作用域不能重复定义相同变量名
3.不能直接修改值和引用地址(const arr[1]=100 修改不了)
4.可以修改引用类型地址的值(arr[1]=100)
2.解构赋值
数组解构
数组解构
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let [a, b, c, d] = arr
console.log(a, b, c, d);
// 中间解构 一个逗号占一个位
let [, , e] = arr
console.log(e);//3
// 复合解构
let arr2 = [1, 2, 3, [10, 20, 30]]
let [f, j, k, [x, y, z]] = arr2
console.log(f, j, k, x, y, z);
字符串解构
字符串解构
// 和数字解构方法一样
let str = "今晚月色真美!"
let [a, b, c, d, e, f, j] = str
console.log(a, b, c, d, e, f, j);
let [, , , , x, y] = str
console.log(x,y);
对象解构
对象解构
let obj = {
name: "小黑",
age: 20,
like: function () {
return "喜欢小白"
}
}
// 解构的定义名必须要和解构的对象里面的属性名一样
let { name, age, like } = obj
console.log(name, age, like());
// 解构API方法
let { random } = Math
console.log(random());
3.对象简化写法
对象简化写法
let name = "小黑"
let age = 20
let like = function () {
return "喜欢小白"
}
// 属性名等于属性值
let obj2 = {
name,
age,
like
}
console.log(name, age, like());
4.模板字符串(`反引号`)
var x = 10
console.log(`把文字直接写里面可以使用'引号'和"双引号",可以换行(\\n)\n变量使用${x}`);
打印:
5.函数参数默认值
//在传参的时候设置默认值
function fun(a = 0, b = 0, c = 0) {
//使用||设置默认值(短路语法)
a = a || 0
b = b || 0
c = c || 0
d = d || 0
return a + b + c + d
}
console.log(fun(1, 2, 3, 4));
//防止实参数少于形参而报错
console.log(fun());
6.函数参数解构赋值
// 数组
function fun([a, b, c]) {
return a + b + c
}
let arr = [1, 2, 3, 4]
console.log(fun(arr));//6
// 对象 形参要和对象的属性名相同
function fun1({a,b,c,d}){
return console.log(a,b,c,d);
}
let obj={
d:40,
c:30,
b:20,
a:10
}
fun1(obj)//10,20,30,40
7.函数参数解构赋值设置默认值
function fun({ url = "www.xxx.com", type = "get", data = { a: 0, b: 0, c: 0 } } = {}) {
console.log(url, type, data);
}
// 如果传递了参数就使用参数
fun({
type: "post",
url: "http:www.xxx.com/xx/xxx",
data: {
a: 10,
b: 20,
c: 30
}
})
// 没有参数就使用默认值 注意加{}
// 因为默认传参是将右边赋值给左边 如果传的不是一个数组或者对象就会报错
// 所以传一个空对象或者在设置默认值的时候赋值一个空对象
// fun({})
// 在上面加了={}下面就不用加{}
fun()
8.rest参数
function fun() {
console.log(arguments);
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
return sum
}
console.log(fun(1, 2, 3, 4, 5, 6, 7, 8, 9);
function fun2(...rest) {
let sum = 0
rest.forEach(function (item) {
sum += item
})
return sum
}
console.log(fun2(1, 2, 3, 4, 5, 6, 7, 8, 9));
var arr = [1, 2, 3, 3, 4, 5, 6, 7, 8, 9]
// ...语法只能在最后使用 接收剩余的所有值形参伪数组
let [a, b, c, ...d] = arr
console.log(a,b,c,d);
9.扩展运算符
// 展开数组
let arr = [1, 2, 3, 4, 5, 6]
console.log(...arr);
// 展开字符串
let sty = "今天的天气很好!"
let [a, b, c, ...d] = sty
console.log(a, b, c, d);
// 展开对象
let obj = {
name: "小白",
age: 10,
gender: "女"
}
// 注意加花括号
console.log({ ...obj });
console.log({ id: "1433223", ...obj });
10.合并数组对象字符串
// 合并数组
let arr = [1, 2, 3]
let arr2 = [4, 5, 6]
console.log(...arr, ...arr2);
// 合并对象
let obj = {
name: "小黑",
age: 10,
gender: "女"
}
let obj2 = {
name: "小白",
age: 20,
gender: "男",
like: "喜欢小黑"
}
// 相同的属性名后面的会覆盖前面的
console.log({ ...obj, ...obj2 });
// 对象方法 assign 把后面的所有对象合并到第一个对象中
// 使用一个空对象来接收,防止污染原来的对象
let newobj = Object.assign({}, obj, obj2)
console.log(newobj);
11.箭头函数
function fun(a, b) {
var sum = a + b
return sum
}
console.log(fun(1, 2));
// 箭头函数
fun2 = (a, b) => {
let sum = a + b
return sum
}
console.log(fun2(2, 3));
// 只有一个参数可以省略小括号
// 只有一行代码可以省略{}
// 只有一行代码和只有返回值可以省略{}和return
fun3 = x => "x值为:" + x
console.log(fun3(10));
//无参数和多个参数不能省略()
// 返回对象,数组不能省略{}和return
fun4 = (x, y) => {
return {
a: x,
b: y
}
}
console.log(fun4(10, 20));
// 箭头函数不能使用arguments 可以使用...rest
// fun5=()=>{
// // argument未定义//没有这个方法
// console.log(arguments);
// }
// fun5(1,2,3,4,5)
fun6 = (...rest) => {
console.log(rest);
}
fun6(1, 2, 3, 4, 5, 6)
// 应用
// 遍历数组
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr.forEach = item => console.log(item);
//定时器
setInterval = (() => console.log("定时器"), 1000);
12.this指向
箭头函数的this指向外一层的this,外一层的this指向什么它就指向什么,因为没有自己的作用域
//在全局中使用this指向window
//函数里面使用this指向window
//定时器中使用this指向window
//事件里面的this指向事件源(触发该事件的对象)
//构造函数里面的this指向最新的实例对象(最后new的对象)
//对象.方法中的this指向该对象
setTimeout(function () {
console.log(this);
}, 1000);
//对象中使用this和对象的方法中使用this
// var name = "var全局作用域的name";
var obj = {
// name: "小白,对象里面的name",
age: 20,
this: this, //对象中的this指向window
eat: function () {
console.log("对象的方法1");
console.log(this.name); //对象方法中的this指向该对象
},
eats: () => {
console.log(this.name); //指向外一层,没有就为undefined
console.log(this);
console.log(
"箭头函数中的this指向外一层作用域,箭头函数本身没有自己的作用域"
);
},
sleep() {
console.log(this);//obj
var eats = () => {
console.log(this.name); //指向外一层的name属性,没有就为undefined
console.log(this);//指向上一层的this 上一层的this指向obj 所以这里的也指向obj obj的this指向window 所以这里也指向window
console.log(
"箭头函数中的this指向外一层作用域,箭头函数本身没有自己的作用域"
);
}
console.log("方法2");
return eats()
},
};
obj.eat(); //对象.方法调用时 里面的this指向该对象
obj.sleep();
console.log(obj.this); //对象中的this指向window
obj.eats(); //箭头函数中的this指向外一层作用域的this,箭头函数本身没有自己的作用域
13.Promise对象
let p = new Promise((resolve, reject) => {
// 默认状态 pending
// 成功状态 fulfiled(成功)
// 失败状态 rejected(拒绝)
resolve() //fulfiled
reject() //rejected
// 状态只会在内部改变 不会受到外部的影响
// 状态发生改变就不会再改变
})
// then catch方法是异步的
// then函数的参数(res)是resolve的响应处理
// catch函数的参数(err)是reject的响应处理
p.then(res => {
console.log("成功" + res);
}).catch(err => {
console.log("失败" + err);
})
Promise解决回调地狱
let p1 = new Promise((resolve, reject) => {
$.ajax({
url: "http://kumanxuan1.f3322.net:8809/travels/query",
type: "get",
success(res) {
resolve("1")
},
error(err) {
reject(err)
}
})
})
let p2 = new Promise((resolve, reject) => {
$.ajax({
url: "http://kumanxuan1.f3322.net:8809/strategies/themes",
type: "get",
success(res) {
resolve("2")
},
error(err) {
reject(err)
}
})
})
let p3 = new Promise((resolve, reject) => {
$.ajax({
url: "http://kumanxuan1.f3322.net:8809/destinations/hotRegion",
type: "get",
success(res) {
resolve("3")
},
error(err) {
reject(err)
}
})
})
p1.then((res) => {
console.log(res);
return p2 //返回p2 后面继续使用 链式语法
}).then((res) => {
console.log(res);
return p3 //返回p3 后面继续使用 链式语法
}).then((res) => {
console.log(res);
})
封装Promise解决回调地狱方法(简化代码)
function fun(url, index) {
return new Promise((resolve, reject) => {
$.ajax({
url,
type: "get",
success(res) {
resolve(index)//这里使用index是为了区分顺序 应该使用res得到数据
},
error(err) {
reject(err)
}
})
})
}
let p1 = fun("http://kumanxuan1.f3322.net:8809/travels/query", 1)
let p2 = fun("http://kumanxuan1.f3322.net:8809/strategies/themes", 2)
let p3 = fun("http://kumanxuan1.f3322.net:8809/destinations/hotRegion", 3)
p1.then((res) => {
console.log(res);
return p2
}).then((res) => {
console.log(res);
return p3
}).then((res) => {
console.log(res);
})
all和race方法
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功1")
// reject('失败1')
}, 3000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功2")
// reject('失败2')
}, 2000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功3")
// reject('失败3')
}, 1000)
})
// all方法的规则 :
// 1. 所有地promise对象都为成功的时候 ,总的结果才为成功,就会执行then方法,得到结果是
// 所有地promise对象resolve返回的结果,以数组的形式体现
// 2. 只要有一个promise的对象状态是失败,总的结果为失败,结果就是 第一个获取到失败的结果
let pall = Promise.all([p1, p2, p3])
pall.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
// race方法
// 谁快就得到谁 不论成功失败
let prace = Promise.race([p1, p2, p3])
prace.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
14.async和await方法
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功1")
// reject('失败1')
}, 3000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功2")
// reject('失败2')
}, 2000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功3")
// reject('失败3')
}, 1000)
})
// async 和 await
async function fun() {
// 其他代码会在await这一行代码执行之后执行
// 如果await后面代码执行时间比这一行短,会在这一行执行的时候按顺序同时执行
// 如果await后面代码执行时间比这一行长,不受影响
await p1.then(res => console.log(res))
await p2.then(res => console.log(res))
await p3.then(res => console.log(res))
console.log("123");
}
fun()