ES6
# ES6
# let
const
var
区别特别重要
let
const
具有块级作用域var
不存在块级作用域- 解决了内层变量覆盖外层、用来计数的循环变量泄露为全局变量的问题
var
存在变量提升let
const
不存在变量提升浏览器的全局对象是
window
Node
的全局对象是global
var
在最外层声明的是全局变量 为该变量添加为全局对象的属性 但是let
const
不会var
允许重复声明 后声明的会覆盖前面的const
let
不允许重复声明暂时性死区 在使用
let
const
声明变量之前 变量不可用 在语法上成为 暂时性死区var
不存在暂时性死区let
可以更改指针的指向const
不能更改指针的指向- 初始值设置
var
let
可以不用设置初始值 而const
声明必须设置初始值
- 初始值设置
区别 | var | let | const |
---|---|---|---|
是否有块级作用域 | × | ✔️ | ✔️ |
是否存在变量提升 | ✔️ | × | × |
是否添加全局属性 | ✔️ | × | × |
能否重复声明变量 | ✔️ | × | × |
是否存在暂时性死区 | × | ✔️ | ✔️ |
是否必须设置初始值 | × | × | ✔️ |
能否改变指针指向 | ✔️ | ✔️ | × |
# const
对象的属性可以修改吗重要
const
保证的是指向的内存地址不改变,对于基本类型的数据(number
string
boolean
),他就是指向那个内存地址
但是引用类型不同(array
object
)变量指向数据的内存地址 保存的只是一个指针 至于他指向的数据结构是不是可变的就不能控制了
# 可不可以new
一个箭头函数出来? new
操作符做了什么?特别重要
箭头函数是ES6
提出的 没有prototype
没有自己this
指向 更没有arguments
参数 所以不能new
一个箭头函数出来
new操作符做了以下几个步骤
var obj = {};
obj.__proto__ = F.prototype;
F.call(obj);
1
2
3
2
3
创建一个对象
将构造函数的作用域赋值给新对象 (将对象的
__proto__
属性指向构造函数的prototype
属性)将构造函数的
this
替换到新对象 然后调用 (也就是将属性和方法加入到this
引用的对象里)隐式返回
this
(返回新的对象)
实现一个
new
// 上面的三部代码为核心代码 那么还有其他的情况
// 来看一个栗子
function Otaku (name, age) {
this.strength = 60;
this.age = age;
return {
name: name,
habit: 'Games'
}
}
var person = new Otaku('shm', '18');
console.log(person.name) // shm
console.log(person.habit) // Games
console.log(person.strength) // undefined
console.log(person.age) // undefined
// 我们这里返回了一个对象 在函数里面我们指定了strength和age的值 但是new出来却是undefined ,说明在实例中只能访问返回的对象中的属性
// 还有一个栗子
// 假如返回的是基本类型的值呢
function Otaku (name, age) {
this.strength = 60;
this.age = age;
return 'say something'
}
var person = new Otaku('Kevin', '18');
console.log(person.name) // undefined
console.log(person.habit) // undefined
console.log(person.strength) // 60
console.log(person.age) // 18
// 跟上面截然相反 有返回值但是没有处理 所以我们要判断一下返回值是不是对象
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
29
30
31
32
33
34
35
36
37
38
39
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
29
30
31
32
33
34
35
36
37
38
39
function objFactory() {
let newObj = Object.create(null);
// 取出参数的第一位
let constructor = Array.prototype.shift.call(arguments);
// result为返回值
let result = null;
// 判断是不是一个函数
if (typeof constructor !== "function") {
console.error("type error");
return;
}
// 新建一个空对象 对象原型为构造函数的prototype对象
newObj.__proto__ = constructor.prototype;
// 将this指向新建对象并调用
result = constructor.apply(newObj, arguments);
// 返回对象
// 这里还要看看构造函数的返回值是不是基本类型的值 还是对象或者函数
return typeof result === "object" ? result : newObj;
}
function Otaku(name, age) {
this.strength = 60;
this.age = age;
return {
name: name,
habit: "Games",
};
}
let temp = objFactory(Otaku, "shm", "20");
console.log(temp.name); // shm
console.log(temp.habit); // Games
console.log(temp.strength); // undefined
console.log(temp.age); // undefined
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
29
30
31
32
33
34
35
36
37
38
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
29
30
31
32
33
34
35
36
37
38
# 箭头函数和普通函数的区别
箭头函数比普通函数更简洁
箭头函数没有自己的
this
- 在自己作用域的上一层继承
this
- 在自己作用域的上一层继承
this
指向永远不变
var id = 'GLOBAL';
var obj = {
id: 'OBJ',
a: function(){
console.log(this.id);
},
b: () => {
console.log(this.id);
}
};
obj.a(); // 'OBJ'
obj.b(); // 'GLOBAL'
new obj.a() // undefined
new obj.b() // Uncaught TypeError: obj.b is not a constructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
call bind apply 不能改变this的指向
var id = 'Global';
let fun1 = () => {
console.log(this.id)
};
fun1(); // 'Global'
fun1.call({id: 'Obj'}); // 'Global'
fun1.apply({id: 'Obj'}); // 'Global'
fun1.bind({id: 'Obj'})(); // 'Global'
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
不能作为构造函数使用
没有自己的
arguments
用的是外层函数的
arguments
没有
prototype
不能用于
Generator
函数 不能用yield
关键字
# 介绍一下Proxy
let p = new Proxy(target, handler)
// target代表需要添加代理的对象 handler用来自定义对象中的操作 比如get set
1
2
2
实现一个数据响应式
let onWatch = (obj, setBind, getLogger) => {
let handler = {
// 这里的receier是改变this的指向的作用
get(target, property, receiver) {
getLogger(target, property)
return Reflect.get(target, property, receiver)
},
set(target, property, value, receiver) {
setBind(value, property)
return Reflect.set(target, property, value)
}
}
return new Proxy(obj, handler)
}
let obj = { a: 1 }
let p = onWatch(
obj,
(v, property) => {
console.log(`监听到属性${property}改变为${v}`)
},
(target, property) => {
console.log(`'${property}' = ${target[property]}`)
}
)
p.a = 2 // 监听到属性a改变
p.a // 'a' = 2
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
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
上次更新: 2022/03/20, 19:40:28