这里仅列出大家容易忽略的知识点,用于查缺补漏~
Symbol
原始数据类型,由Symbol函数生成。
//正确.返回具有唯一性的值
Symbol()
Symbol(label)
//错误
//因为返回的是原始类型;同undefined;null;Boolean;String;Number;
//对象(Object、Array、Function)是引用数据类型。
new Symbol()
不能做字符串拼接等运算操作,但可以显示转换为字符串:Symbol().toString() //"Symbol()"
.
应用:
1.作为对象属性
//获取Symbol的方法:
Object.getOwnPropertySymbols(obj) //获取对象的Symbol属性名
Reflect.ownKeys(obj) //获取对象自身所有属性,包括不可枚举以及Symbol
可以在封装对象时,将Symbol用作非私有,但只用于内部访问的属性。(挂在对象上,但外部拿不到Symbol值就无法访问其对应的值)。
2.作为常量值
3.Symbol.for(label)
全局登记的方式,只有未找到的情况下才会返回新的Symbol值;利用其全局环境搜索的这个特性,可以跨iframe
获取值。
4.内置Symbol值
执行对象(Object或String等)原型上特定的内部方法时,会自动执行对象对应的Symbol对应的函数。
举两个典型的例子:
1. Symbol.iterator
- 其值为对象的遍历器对象生成器
- 当使用for...of()循环时,会自动调用对象的Symbol.iterator方法
//for...of ES6提供的统一的访问数据结构的接口
2. Symbol.toStringTag
//使用Object.prototype.toString方法,会先找对象的Symbol.toStringTag
({[Symbol.toStringTag]: 'M2'}).toString(); //"[object M2]"
Proxy | Reflect
ES6 为操作【对象】
而提供的新 API。
Reflect
- 内部方法:Proxy this问题 Reflect解决
- 对象操作,部分命令式操作变成函数行为,如:
delete obj.attr
变为Reflect.deleteProperty(obj, attr)
- 和Proxy方法一一对应
Set | Map
特性:
set:保证值的唯一性;去重。
map: 相对于对象,是一种更完善的hash结构实现。
适用使用for...of
实现遍历的各种场景,如扩展运算符等。
Map 结构的默认遍历器接口(Symbol.iterator
属性),就是entries
方法。
map[Symbol.iterator] === map.entries
Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values
方法。
Set.prototype[Symbol.iterator] === Set.prototype.values
WeakSet | WeakMap
- 只接受对象作为键名;
- 弱引用,不计入垃圾回收;防止内存泄漏,但也导致不支持遍历和size。
用途:1)dom元素的记录or操作 2)私有方法 | 私有属性
Object
1.比较两个值是否完全相同
//除了+0和-0不等;NaN等于自身。别的等同于===
Object.is(a,b)
2.对象的合并;之拷贝对象自身可枚举的属性
//原始类型会被转换成对象
Object.assign(2) //Number{2}
//原始类型只有字符串可以被拷贝到对象上,因为其可遍历(结合iterator理解)
Object.assign({}, 2, '3'); //{0: "3"}
//数组的替换
Object.assign([1,2,3], [4,5]) //[4,5,3]
3.设置|获取对象原型
Object.setPrototypeOf(target, prototype);
Object.getPrototypeOf(target);
4.遍历
Object.keys()
Object.values()
Obeject.entries() //对象转键值对数组
5.键值对数组转对象
Object.fromEntries() //entries的逆操作;因此适合将Map结构转为Object
Object.getOwnPropertyDescriptors()
返回指定对象所有自身属性(非继承属性)的描述对象。
主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。getOwnPropertyDescriptors不仅会返回对象属性,而且包括其属性描述器。
obj={a:'a',b:'b'}
Object.getOwnPropertyDescriptors(obj);
//output:
{
a:{value:"a",writable:true,enumerable:true,configurable:true}
b:{value:"b",writable:true,enumerable:true,configurable:true}
}
应用:可以结合Object.assign
、Object.create
Object.create(proto[, propertiesObject])
作用:创建一个新对象,使用已有对象作为新创建对象的__proto__
;
propertiesObject可选,默认为创建对象的自有属性;
o = Object.create({a:1}, {
foo: {
value: "hello"
}
})
o.hasOwnProperty('foo') //true
省略了的属性特性默认为false,所以属性foo是不可写(writable)、不可枚举(enumerable)、不可配置(configurable)。
常见示例:
- 创建空对象
1. obj = {};
等价于
obj = Object.create(Object.prototype);
2. obj = Object.create(null); //创建一个原型为null的空对象
- 子类继承父类时使用
// 子类续承父类
Rectangle.prototype = Object.create(Shape.prototype);
/*
* 等价于
* function prototypeCerate(o) {
* function F() {}
* F.prototype = o;
* return new F();
* }
* Rectangle.prototype = prototypeCerate(Shape.prototype);
*/
Rectangle.prototype.constructor = Rectangle;
super
指向当前对象的原型对象;【作为构造函数 | 原型对象】
//指向原型对象时,只能用在对象方法中,如下:
const obj = {
getName() { super.getName(); }
}
//错误. super被用在普通函数里面,该函数被赋值给getName。
const obj = {
getName: () => super.getName()
}
内部原理:
super.foo
//1.作为原型属性:
Object.getPrototypeOf(this).foo
//2.作为原型方法:
`bject.getPrototypeOf(this).foo.call(this)
扩展运算符
//数组转对象。深刻理解iterator遍历
let a = { ...['a', 'b', 'c'] }; // {0: "a", 1: "b", 2: "c"}
//与解构赋值结合
[a, ...rest] = [1,2,3]
数组实用方法
[1, 2, 7, 4].find((n) => n >5); //7;返回第一个满足条件的值
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}); // 2;返回第一个满足条件的下标
['a', 'b', 'c'].fill(7, 1, 3) // ['a', 7, 7]
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
Array.of(1, 2) // [1, 2]
函数
参数作用域
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。
//Example1
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2) // 2
//Example2
var x = 1;
function foo(x = x) { //等价于let x = x;暂时性死区
}
foo() // ReferenceError: x is not defined
//Example3
function f(y = x) {
let y = 2;
console.log(y);
}
f() //Identifier 'y' has already been declared
let & const
- 不存在变量提升
console.log(bar); // Uncaught ReferenceError: Cannot access 'bar' before initialization
let bar = 2;
- 暂时性死区
区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
//example1
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
//example2
let x2 = x2; // ReferenceError
- 块级作用域
// IIFE 写法
(function () {
var tmp = ...;
...
}());
// 块级作用域写法
{
let tmp = ...;
...
}
- 声明变量的方式
var、function、let、const、import、class
- 顶层对象的属性
浏览器:window(this 、 self)
Node:global
更多技术分享,欢迎【扫码关注】~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。