let const 区别: let和const的相同点:
① 只在声明所在的块级作用域内有效。
② 不提升,同时存在暂时性死区,只能在声明的位置后面使用。
③ 不可重复声明。
2、let和const的不同点:
① let声明的变量可以改变,值和类型都可以改变;const声明的常量不可以改变,这意味着,const一旦声明,就必须立即初始化,不能以后再赋值。
打个比方说:
let x = 3;
x = 4;
这样子是可以的,因为let声明的变量是可以修改或者重新定义的。
再比如:
const x = 4;
x = 5;
这是错误的,因为const声明的变量是不可修改并且必须马上赋初值。
class
class 声明创建一个基于原型继承的具有给定名称的新类。
用法:
class Polygon {
constructor(height, width) {
this.area = height * width;
}
}
console.log(new Polygon(4, 3).area);
继承: extends
class Square extends Polygon {
constructor(length) {
super(length, length);
this.name = 'Square';
}
}
子类 super(): 子类没有自己 this
若之前使用类表达式定义了一个类,则再次声明这个类同样会引起类型错误。
私有变量: TS
静态方法, 静态属性
解构对象
数组 对象 怎么解构赋值
数组: const [a, b] = [1, 2]
对象: const { a, b: b2 } = { b: 1, a: 2 }
我不定义第三个变量, 只定义2个变量 怎么交换这个2个变量的值
[a, b] = [b, a]
const { a = 1 } = { a: undeinfind }
函数:
函数 this定义: this代表当前正在执行的对象
箭头函数 this: 箭头函数 没有自己的 this, 他会把上一层作用域链的this当成自己的this
改变this指针: call apply bind (背一下 call apply)
箭头函数和普通函数区别: 1. 箭头函数不能当类使用 2. 没有自己的this 3. arguments
new 函数 会经过哪些步骤: 1. 创建一个空对象 2. 执行构造器 3. 给this挂在变量 4. 返回这个
对象给定义的接收变量
const obj = new (function fn () {})
作用域链 背一下
继承: 寄生组合式继承
数组:
数组有哪些循环方式: filter map reduce find findIndex forEach
数组的常用的方法 属性:
1、给数组末尾添加新内容的push方法;
2、删除数组最后一项的pop方法;
3、删除数组第一项的shift方法;
4、向数组首位添加新内容unshift方法等等。
对象:
Object.keys()
方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
Object.values()
方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用 for...in 循环的顺序相同(区别在于 for-in 循环枚举原型链中的属性)。
Object.values(obj)
Object.defineProperty 用法
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false
});
object1.property1 = 77;
// Throws an error in strict mode
console.log(object1.property1);
// Expected output: 42
Symbol
用法: Symbol()
是一种基本数据类型(primitive data type)。Symbol() 函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。
作用: 创建的变量唯一值
每个从 Symbol() 返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的。
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');
console.log(typeof symbol1);
console.log(symbol2 === 42);
console.log(symbol3.toString());
console.log(Symbol('foo') === Symbol('foo'));
Proxy:
Proxy :
定义:对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义
使用:
我们在vue.config.js文件中设置proxy
devServer: {
proxy:{
"/api": {
target: "http://www.baidu.com", // 当我们发送请求时的URL中有/api时,会将在/api前面的路径替换成target的值。
changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
pathRewrite: { //重写匹配的字段,如果不想出现在请求路径上,可以重写为""
"^/api": "/api"
}
},
},
}
Proxy defineProperty 区别:
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。IE8不兼容。
Object.defineProperty(obj, prop, descriptor)
参数
obj: 要定义属性的对象。
prop: 要定义或修改的属性的名称或 Symbol 。
descriptor: 要定义或修改的属性描述符。
Promise 必考
有几种状态: 3种
1: 进行中 pending: 初始状态,不是成功或失败状态
2:已成功 fulfilled: 意味着操作成功完成。
3:已完成rejected: 意味着操作失败。
一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有哪些 属性 方法:
then方法:
promise.then((value) => {}, (error) => {}) 可接收两个回调函数作为参数;第一个回调是Promise对象状态变为resolved时调用,第二个回调是状态变为rejected时调用;这俩函数都是可选的。
catch方法:
Promise.prototype,catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名。
Promise.all([p1, p2, p3]):
都成功才会成功,有一个失败就会变成rejected
Promise.race() :
哪个最快就返回哪个的结果,不管别的执没执行完成
Generator
function* generator() {
yield 1;
yield 2;
yield 3;
}
const gen = generator(); // "Generator { }"
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
async 必考
用法: async await
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数。
同时请求3接口 全部执行完, 拿到返回值:
async function () {
const xxx = await Promise.all([ajax1, ajax2, ajax3])
}
async 实现原理:
async function fun0(){
console.log(1);
return 1;
}
fun0().then(val=>{
console.log(val) // 1,1
})
async function fun1(){
console.log('Promise');
return new Promise(function(resolve,reject){
resolve('Promise')
})
}
fun1().then(val => {
console.log(val); // Promise Promise
})
await
await 也是一个修饰符,只能放在async定义的函数内。可以理解为等待。
await 修饰的如果是Promise对象:可以获取Promise中返回的内容(resolve或reject的参数),且取到值后语句才会往下执行;
如果不是Promise对象:把这个非promise的东西当做await表达式的结果。
async function fun(){
let a = await 1;
let b = await new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('setTimeout')
},3000)
})
let c = await function(){
return 'function'
}()
console.log(a,b,c)
}
fun();
Module
AMD CMD === import
export 与 import 的复合写法
如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。
export { foo, bar } from 'my_module';
// 可以简单理解为
import { foo, bar } from 'my_module';
export { foo, bar };
export和import语句可以结合在一起,写成一行。
但需要注意的是,写成一行以后, foo和 bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用 foo和 bar。
// 接口改名
export { foo as myFoo } from 'my_module';
// 整体输出
export * from 'my_module';
默认接口
export { default } from 'foo';
具名接口改为默认接口的写法如下。
export { es6 as default } from './someModule';
// 等同于
import { es6 } from './someModule';
export default es6;
同样地,默认接口也可以改名为具名接口。
export { default as es6 } from './someModule';
有一种import语句,没有对应的复合写法。
import * as someIdentifier from "someModule";
ES2020补上了这个写法。
export * as ns from "mod";
// 等同于
import * as ns from "mod";
export {ns};
装饰器:
要想了解装饰器,首先要了解一个概念,闭包。什么是闭包,一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。