# var,let,const 的区别

1.var 变量可以提升,let,const变量不可以提升
2.var 没有暂时性死区,let,const有暂时性死区
3.var 允许重复声明,let,const不可以重复声明
4.var 和let可以修改声明的变量,const不可以修改
5.var 没有块级作用域,let和const有块级作用域

# 箭头函数和 function 的区别

1.箭头函数是匿名函数,不能作为构造函数,不能使用new
2.箭头函数内没有arguments,可以用展开运算符...解决
3.箭头函数的this,始终指向父级上下文(箭头函数的this取决于定义位置父级的上下文,跟使用位置没关系,普通函数this指向调用的那个对象)
4.箭头函数不能通过call() 、 apply() 、bind()方法直接修改它的this指向。(call、aaply、bind会默认忽略第一个参数,但是可以正常传参)
5.箭头函数没有原型属性

# 结构赋值

1 结构赋值就是从对象或数组中提取值,吧右边的值赋给左边
2 分为数据结构,对象结构,结构赋值,结构对象,从方法中返回

# 原型

实例化对象和原型的constructor指向构造函数
构造函数的prototype属性指向原型对象
实例化对象的__proto__属性指向原型对象
JavaScript里面每个对象都有一个__paoto__属性,这个属性就是他的原型
每个方法里面都有一个prototype属性,也是他的原型
1
2
3
4
graph LR
A[实例化对象和原型] -- constructor --> B(构造函数的)
B-- prototype --> D(原型对象)
D-- 实例化对象的__proto__--> E(原型对象)

# 原型链

实例化对象的 proto 指向构造函数的 prototype
构造函数 prototype 的 proto 指向 Object.prototype
Object.prototype 的 proto 指向 null

1
2
3
4
graph LR
A[实例化对象] -- __proto__ --> B(构造函数的prototype)
B-- __proto__ --> D(Object.prototype)
D-- __proto__--> E(null)

# 继承

# 1. 原型链继承

父类的实例做为子类的原型

1
2
3
4
5
6
7
function Fu() {
this.arr = ["red", "blue", "green"];
}
function Zi() {}
Zi.prototype = new Fu();
var a = new Zi();
a.arr.push("black");
# 2. 构造函数继承

在子类内,使用 call 调用父类方法,并将父类的 this 修改为子类的 this,相当于是吧父类的实例属性复制了一份放到子类的函数内

1
2
3
4
5
6
7
8
9
function Fu() {
this.arr = ["red", "blue", "green"];
}
function Zi() {
Fu.call(this);
}
var a = new Zi();
a.arr.push("black");
console.log(a.arr);
# 3. 组合式继承

既能调用父类实例属性,又能调用父类原型属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Fu(name) {
this.name = name;
this.arr = ["red", "blue", "green"];
}
Fu.prototype.say = function () {
console.log(this.name);
};
function Zi(name, age) {
Fu.call(this, name);
this.age = age;
}
Zi.prototype = new Fu();
var a = new Zi("black", 21, "女");
a.say(); //成功继承
# 4.class 类继承

相当于 es5 中构造函数
class 中定义方法时,前后不能加 function,全部定义在 class 的 protopyte 属性中
class 中定义的所有方法是不可枚举的
class 中只能定义方法,不能定义对象,变量等
class 和方法内默认都是严格模式
es5 中 constructor 为隐式属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Fu(){
constructor(name){
this.name=name
}
say(){
console.log(this.name)
}
}
class Zi extends Fu{
constructor(name,age){
super(name)
this.age=age
}
say(){super.say()}
}
var a=new Zi('张三')
a.say()

# Promise

1. 概述 :Promise 是异步编程的一种解决方案,从语法上讲,Promise 是一个对象,可以获取异步操作的消息 2. 目的 : (1)、避免回调地狱的问题(2)、Promise 对象提供了简洁的 API,使得控制异步操作更加容易
3.Promise 有 三种状态 :pendding // 正在请求,rejected // 失败,resolved // 成功 4. 基础用法 :new Promise (function (resolve,reject){ })
resolved,rejected 函数:在异步事件状态 pendding->resolved 回调成功时,通过调用 resolved 函数返回结果;当异步操作失败时,回调用 rejected 函数显示错误信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(function () {
// 封装一个promise;将url提取出来;
var p = function (url) {
return new Promise(function (resolve, reject) {
$.get(url, function (data) {
resolve(data);
});
});
};
Promise.all([
p("https://cnodejs.org/api/v1/topics?tab=good"),
p("https://cnodejs.org/api/v1/topics?tab=share"),
]).then(function (result) {
console.log(result);
});
});

# async 和 await

async 其实就是 promise 的语法糖,可以让普通函数变为一个异步函数,返回的是一个 promise 对象

1.async使用在函数前面,把函数变成一个异步函数,返回值是个promise对象。
2.await只能使用在async声明的函数里,不能使用在普通函数里。
3.异步操作方法的前面要加关键字await 意思就是等一下,是可以等到你的数据加载过来以后才会去运行下边的 js 内容,而且 await 接收的 对象必须还是个 promise 对象。,注意:async和await必须一起使用,否则会报错。
4.async/await 可以解决异步,回调地域

# Generator

要了解 Generator 就要先了解他出现的原因

1.当初设计是为了解决地域回调问题的
2.因为当时的promise解决地域回调代码量过多
3.出现generator没多久async/await就出来了
4.于是generator就处于一个尴尬的境地,慢慢的被人遗忘了

语法上 ,Generator 函数是一个状态机,封装了多个内部状态。
形式上 ,Generator 是一个函数。不同于普通函数,是可以暂停执行的,所以函数名之前要加星号,以示区别。
整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器,异步操作需要暂停的地方,都用 yield 语句。

1.function 关键字和函数之间有一个星号(*),且内部使用yield表达式,定义不同的内部状态。
2.调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。
3.Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

总结一波

从回调函数,到 promise, 再到 generator, 再到 Async/await, 这四种分别代表了 JavaScript 异步编程解决方案的进化路程。async 和 generator 函数主要就是为了解决异步的并发调用使用的 ,直接将参数从 then 里取出来,相比 promise 的链式调用,传参更加方便,异步顺序更加清晰

# 深拷贝和浅拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//深拷贝
let obj = [0, 1, 2, 5];
let arr = JSON.stringify(obj);
let es = JSON.parse(arr);
es[0] = 99;
console.log(obj, es);
//浅拷贝
let a = [0, 2, 3, 4];
let b = a.slice();
a[1] = 000000000;
console.log(a, b);
//浅拷贝
let a = [0, 1, 2, 3];
var b = a;
b[0] = 000000000000000;
console.log(a, b);

# 闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//方法一
function foo() {
var a = 111;
return function () {
console.log(a + 333);
};
}
let q = foo();
q();
//方法二
var es = (function () {
var i = 222;
return function () {
console.log(i);
};
})();
es();
//方法三
function foo() {
var a = 111;
function es() {
console.log(a + 333);
}
return {
es,
};
}
foo().es();
更新于

请我喝[茶]~( ̄▽ ̄)~*

高祥 微信支付

微信支付

高祥 支付宝

支付宝

高祥 贝宝

贝宝