变量与常量
| 区别 | var | let | const |
|---|---|---|---|
| 定义 | 局部变量 | 局部变量 | 局部常量 |
| 声明作用域 | 函数作用域 | 块作用域 | 块作用域 |
| 声明提升 | 变量声明会提升到函数作用域的顶部 | 不提升 | 不提升 |
| 声明次数 | 作用域中可重复多次声明同一个变量 | 作用域中只能一次 | 作用域中只能一次,在不同作用域或不同块级作用域中可以重新声明赋值 |
| 全局声明 | 使用var在全局作用域中声明的变量会成为window对象的属性 | 使用let在全局作用域中声明的变量不会成为window对象的属性 | |
| 声明和使用 | 可先声明后使用,也可先使用后声明 | 需要先声明再使用 | 声明时必须进行初始化,且初始化后不可再修改 |
| 条件声明模式 | 可 | 不可 | |
| 循环中声明 | 可声明迭代变量,后台会为每个迭代变量声明一个新迭代变量 | 不可声明迭代变量,因为迭代变量会自增 | |
| 其他 | const声明的限制只适用于它指向的变量的引用,必须进行初始化 |
- 局部变量会在函数运行以后被删除,函数参数只在函数内起作用,是局部变量
- 全局变量会在页面关闭后被删除,全局变量是 window 对象: 所有数据变量都属于 window 对象
数据类型
基本类型(值类型)
- String:字符串
- Number:数字
- Boolean:布尔值
- Null:空,typeof返回object
- Undefined:未定义,typeof返回undefined
- Symbol:独一无二的值,Symbol 是 ES6 引入了一种新的原始数据类型 引用数据类型
- Array:数组,是一种特殊的对象类型,typeof返回object
- Object:对象
- Function:函数
运算符
算数运算符
| 运算符 | 描述 |
|---|---|
| + | 加 |
| - | 减 |
| * | 乘 |
| / | 除 |
| % | 取余 |
| ++ | 自增 |
| -- | 自减 |
赋值运算符
| 运算符 | 例子 | 含义 |
|---|---|---|
| = | ||
| += | x+=y | x=x+y |
| -= | x-=y | x=x-y |
| *= | x*=y | x=x*y |
| %= | x%=y | x=x%y |
比较运算符
| 运算符 | 描述 |
|---|---|
| == | 等于 |
| === | 绝对等于(值和类型均相等) |
| != | 不等于 |
| !== | 不绝对等于(值和类型有一个不相等,或两个都不相等) |
| 大于 | |
| < | 小于 |
| >= | 大于或等于 |
| <= | 小于或等于 |
逻辑运算符
| 运算符 | 描述 |
|---|---|
| && | 并 |
| // | 或 |
| ! | 不 |
条件运算符
variablename = (condition) ? value1 : value2
this
//方法中,指向该方法所属对象
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
//this--->person
return this.firstName + " " + this.lastName;
}
};
//单独使用,指向全局(Global)对象
//this--->window
var x = this;
//函数中,默认指向全局(Global)对象,严格模式下指向undefined
//this--->window
function myFunction() { return this; }
//this--->undefined
"use strict";
function myFunction() { return this; }
//事件中,指向接收事件的HTML元素
//this---><button>
<button onclick="this.style.display='none'"> 点我后我就消失了 </button>
//每个函数都包含两个非继承而来的方法:call()和apply()
//call() 和 apply() 方法可以将 this 引用到任何对象
apply与call
写法:有区别
/*apply()方法*/
B.apply(A, arguments);//即A对象应用B对象的方法
/*call()方法*/
B.call(A, args1,args2);//即A对象调用B对象的方法
- A:将替代B的this对象
- arguments:数组、类数组、参数列表
- arg1,arg2...:参数
作用:相同,改变某个函数运行时的上下文(context),即改变函数体内部this的指向
- 改变函数作用域
var name = "小白";
var obj = {
name: "小红"
};
function sayName() {
return this.name;
}
//调用sayName()方法返回this对象中name变量
console.log(sayName.call(this)); //小白
//调用sayName()方法返回obj对象中name变量
console.log(sayName.call(obj)); //小红
- 实现继承、多重继承
function A(){
this.showSub = function(a,b){
alert(a - b);
}
}
function B(){
this.showAdd = function(a,b){
alert(a + b);
}
}
function C(){
A.apply(this);
B.apply(this);
//A.call(this);
//B.call(this);
}
var c = new C();
c.showSub(3,1); //2
c.showAdd(3,1); //4
应用:
- Math.max.apply(null,array)
Math.max(param1,param2...)//不支持Math.max(paramsArray)
--->
Math.max.apply(null,paramsArray)//将数组中paramsArray的数一个个传入
- Array.prototype.push.apply(objArray,paramsArray)
paramsArray.map(item=>{
objArray.push(item)
})
--->
Array.prototype.push.apply(objArray,paramsArray);//将paramsArray数组中的数一个个通过push方法推入objArray中
promise
new Promise(function (resolve, reject) {
// 要做的事情...
if (/* 异步操作成功 */) {
resolve(value);//函数,由js引擎提供
} else {
reject(error);//函数,由js引擎提供
}
});
状态:对象状态不受外界影响
- Pending:进行中
- Fulfilled:已成功
- Rejected:已失败 状态改变:一旦状态改变就不会再变
- resolve():Pending -> Fulfilled
- reject():Pending -> Rejected
new Promise(function (resolve, reject) {
if (/* 异步操作成功 */) {
resolve(value);
} else {
reject(error);
}
})
.then(function (value) {
console.log(value);
})
.catch(function (error) {
console.log(err);
})
.finally(function () {
console.log("End");
});
方法:
- then():将参数中的函数添加到当前 Promise 的正常执行序列
- catch():设定 Promise 的异常处理序列
- finally():在 Promise 执行的最后一定会执行的序列
//做多重的异步操作,会导致经典的回调地狱
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
//把回调绑定到返回的 Promise 上,形成一个 Promise 链
doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
//简写
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`);
})
.catch(failureCallback);
链式调用:连续执行两个或者多个异步操作
new Promise((resolve, reject) => {
console.log(1);
resolve();
})
.then(() => {
throw new Error('error');
console.log(2);
})
.catch(() => {
console.log(3);
})
.then(() => {
console.log(4);
});
//执行顺序:1->3->4
catch 的后续链式操作:在一个回调失败之后继续使用链式操作
Promise.all([promise1, promise2, promise3])
.then(([result1, result2, result3]) => { /* use result1, result2 and result3 */ });
Promise.race([promise1, promise2])
.then((value) => { /* use faster value*/ });
api:
- Promise.all():所有的都有完成,相当于且
- Promise.race():完成一个即可,相当于或
let promise = new Promise(function(resolve, reject){
console.log(1);
resolve()
});
promise.then(() => console.log(2));//传递到then()中的函数被置入到一个微任务队列中,而不是立即执行,在JavaScript事件队列的所有运行时结束且事件队列被清空之后,才开始执行
console.log(3)
//执行顺序:1->3->2
let promise = new Promise(function(resolve, reject){
console.log(1);
resolve()
});
await promise;
await new Promise((resolve, reject)=>{
console.log(2);
resolve();
});
console.log(3)
//执行顺序:1->2->3
let promise = new Promise(function(resolve, reject){
console.log("1");
resolve();
});
setTimeout(()=>console.log("2"), 0);//浏览器API
promise.then(() => console.log("3"));//引擎内部任务
console.log("4");
//执行顺序:1->4->3->2
时序:then()-->setTimeout()
async/await
-
async:异步函数,可以使用 await 指令,await 指令后必须跟着一个Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行
-
await:命令,后接Promise对象并返回该对象结果。如果不是 Promise 对象,就直接返回对应的值。另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于Promise对象
function print(delay, message) {
//delay:时间,message:消息
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
//promise原生写法
print(1000, "First")
.then(function () {
return print(4000, "Second");
})
.then(function () {
print(3000, "Third");
});
//async/await写法
await print(1000, "First");
await print(4000, "Second");
await print(3000, "Third");