let , const
-
const
与let
的区别:1. 声明时必须赋值 2.只能赋值一次 - let 存在暂时性死区:
let
会使变量作用域绑定在当前块内;那么这个变量在let之前是未定义的,但它又不能取父作用域的同名变量的值
暂时性死区
for(let i=0;i<3;i++){
//此时i的作用域就在括号内
//但js会自动帮用户在花括号内创建一个同名临时变量i,使得i在打印时不会固定变为3
button[i].onclick = ()=>{
console.log(i)
}
}
Symbol
当我不关心一个一个变量的值,只希望区分该变量与其他变量时
x = Symbol()
默认参数值
- 当传给函数的参数值为undefined时,默认参数值会生效
- function x(a,...b) {} 得到的b是一个数组
- 伪数组转数组两种方法
let arr = Array.from(arguments)
let arr = [...arguments]
- 简单的值交换
let [a,b] = [1,2];
[a,b] = [b,a]
console.log(a,b) //2,1
需要特别注意的是,在这种情况下,值交换的前一句结束分号一定不能省略,否则会出错
- 双层解构赋值
var obj = {x:{b:1}}
var {x:{b}} = obj
console.log(b) //1
//先 x = obj.x 而后 b = x.b
- Object.assign()是浅拷贝,或者说只能深拷贝一层
对象属性增强
let obj = {x,y}
- 对象声明时键名可以用表达式
模块化
- 依赖:用到了别的模块
- 导出:给别的模块用
- 在不同模块中多次导入同一个模块,该模块也只会被下载一次,但会执行多次
-
import
语句只能在声明了type="module"
的 script 的标签中使用
import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";
- export
export { name1, name2, …, nameN };
export default expression;
export * from …;//模块透传
class
- 如何不用class实现继承
function Animal(){
this.a = 1
}
Animal.prototype.move = function(){}
function Human(){
Animal.apply(this,aruguments)
this.b = 2
}
let f = function(){}
f.prototype = Animal.prototype
Human.prototype = new f()
Human.prototype.constructor = Human
转自知乎《JS的new到底是干什么的》——方应杭
- 使用class实现继承
class Human extends Animal{
constructor(){
super()
}
}
- 类:拥有共同属性的对象
- constructor用于构造自有属性
- extends会使原型链再多一层
- 在继承时,用到了this就要在使用前加super()
- class不支持公有属性是非函数
- 用
get
设置可读不可写的属性
class Human{
constructor(age){
this._age = age
}
get age (){
return this._age
}
}
var human = new Human(19)
console.log(human.age) // 19
- 用set对属性的写操作进行响应的限制
class Human{
constructor(name){
this._name = name
}
set name (value){
if(value>4){console.log('名字长度不能超过4个字')}
else{this._name = value}
}
}
var human = new Human('yyh')
human.name('哈哈哈哈哈哈哈') //名字长度不能超过4个字
- static 用于声明构造函数的静态方法
promise
- promise解决了多层的异步嵌套。增加了代码的可读性
- 手写promise
function fn (){
return new Promise((resolve,reject)=>{
if(x){resolve()}
else{reject()}
}
function rs1(){
//...
if(x){return Promise.resolve()//如果不写明返回值,默认返回resolve
}else{ return Promise.reject()}
}
}
function rj1(){
if(x){return Promise.resolve()//如果不写明返回值,默认返回resolve
}else{ return Promise.reject()}
}
fn().then(rs1,rj1)
promise.catch()
- 如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。因为执行完它自己的catch方法后,该实例的状态也会变成resolved
- 只要函数中有错误,就会进入
reject()
,而reject()
等同于抛出错误。Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。 - 比较下面两种写法
// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误。应该说如果想要捕获then方法执行中的错误,应该这么写
promise
.then(function(data) {
// success
}, function(err) {
// error
}).then(function(data){},function(err){});
then的第二个参数,只能处理上一层函数的错误,而不能处理上上层的错误,所以第二种写法优于第一种写法
- 跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。这就是说,Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。
Promise.prototype.finally()
- finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
Promise.all()
- 参数是由promise对象构成的数组
- 返回值分两种,数组内promise对象的状态都为成功后,返回对象成功后的返回值构成的数组;数组内promise对象有一个失败,返回第一个失败的对象的返回值
promise.race()
const p = Promise.race([p1, p2, p3]);
- 上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
async&await
- async function 用于声明一个返回Promise对象的函数。该函数内部会有异步操作。async的优点在于处理 then 链,该声明使异步函数看起来像同步函数一样
-
async
函数中可能会有await
,await
后面接一个Promise对象,这会使async
函数暂停执行,等待Promise
的结果出来,然后恢复async
函数的执行并返回解析值(resolved)。 - 正常情况下,await可以接一个 Promise 对象,返回该对象的结果。它会阻塞后面的代码,如果不是 Promise 对象,就直接返回对应的值。
- 任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
- 这篇文章写的是真真好:https://segmentfault.com/a/1190000007535316
网友评论