前端培训-中级阶段(32)- set、map、proxy、reflect、generator(2020-01-02期)

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,如今前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提高技术水平,打牢基础知识的中心思想,咱们开课啦(每周四)。javascript

前言BB

这节标题超长了,难受箭头函数、set、map、proxy、symbol、reflect、generator前端

箭头函数

以前声明函数使用 function funName(arg1,...args){return args}
ES6 增长了新的声明函数方式 (arg1,...args)=>argsvue

箭头函数的特色

  1. 匿名函数。经过上面例子能够看出,匿名函数没有名字。用法等价于以前的函数表达式
  2. 简洁[1,2,3,4,0,-1,-2,-3].map(v=>Math.sign(v))java

    1. 入参的省略。若是只有一个入参,那么括号能够省略。没有入参、多个入参、rest 参数(...)、解构({status, response})都须要加括号。image.png
    2. 函数体的省略。若是没有花括号,那么只能传入一个表达式,表达式的结果会 return。若是有花括号,就须要显式的return,固然也能够不写默认 returnundefined
  3. this 指向es6

    1. 箭头函数的 this 对象指向定义时所在的对象,而不是使用时所在的对象。
    2. 箭头函数的 this 对象是不可变的。bind、call、apply、赋值等操做都没法改变。
  4. 不能够当作构造函数。由于上面的 this 问题。
  5. 没有 arguments
  6. 不能用做 Generator 函数。不可使用 yield 命令

箭头函数的一些错误用法

  1. 不该该在声明对象的时候使用。由于这个时候里面的 this 指向定义时的环境。编程

    obj = {
      name: 'app',
      jumps: () => {
        console.log(this.app);
      }
    }

Set、WeakSet

Set 特色是值惟一有序。相似于数组,可是成员的值都是惟一的,没有重复的值,遍历的话是插入顺序。Array.from(new Set([1,2,3,1,1,2,3,1])) 依赖值惟一的特性实现去重。
image.pngsegmentfault

Set 构造函数

new Set([iterable]); 使用可迭代的数组来建立。数组

  1. new Set([1,2,3,4,2,1,1,1,12,3])
  2. new Set('123123')
  3. new Set(['123123',1,2,3])
  4. new Set(document.querySelectorAll('a'))
  5. image.png

属性和方法

  1. Set.prototype.size:返回总数,等价于(Array.prototype.length
  2. Set.prototype.add(value):添加,返回当前对象可链式操做。
  3. Set.prototype.delete(value):删除,返回一个布尔值,表示删除是否成功。
  4. Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
  5. Set.prototype.clear():清除全部成员,没有返回值。
  6. Set.prototype.keys():返回键(key)遍历器 Iterator
  7. Set.prototype.values():返回值(value)遍历器 Iterator
  8. Set.prototype.entries():返回键值对([key, value])遍历器 Iterator
  9. Set.prototype.forEach():使用回调函数(value, key, this)=>遍历每一个成员

WeakSet

  1. 只能存放对象的集合
  2. 弱引用方式保存。弱引用就是能够被垃圾回收(若是放入数组,那么你不知道什么实际是能够被回收的,由于数组是强引用),
  3. 没有总数
  4. 不可枚举

image.png

Map、WeakMap

Map 其实 和 JavaScript 的对象(Object)同样,本质上是键值对的集合Hash 结构)。
可是传统上 Object 只能用字符串看成键,在使用上有很大的局限性。微信

Map 的数据结构也能够理解为对象,是键值对的集合
可是 key 的范围不限于字符串,能够是其余类型(包括对象)均可以看成键。是一种更完善的 Hash 结构实现。数据结构

userinfo = {name: 'lilnong.top'}
map = new Map()
map.set(userinfo, {age: 123})
map.has(userinfo)
map.get(userinfo)

image.png

构造函数

map = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
]);
map.forEach(
  (key, value) => console.log(key, value)
);

image.png

属性和方法

  1. size 返回记录总数。(Object 但是没有这个属性的哟)
  2. set(key, value) 赋值操做
  3. get(key) 取值操做
  4. has(key) 判断当前 key 是否存在于集合中。
  5. delete(key) 删除操做。返回 true,代表删除成功。返回 false 代表删除失败,好比你删除了一个不存在的 key
  6. clear() 清空全部。
  7. 遍历方法。(插入顺序)

    • Map.prototype.keys():返回键名的遍历器。
    • Map.prototype.values():返回键值的遍历器。
    • Map.prototype.entries():返回全部成员的遍历器。
    • Map.prototype.forEach():遍历 Map 的全部成员。

weakMap

WeakMap 只接受对象做为键名null除外),不接受其余类型的值做为键名。
WeakMap键名所指向的对象,不计入垃圾回收机制
由于是弱引用,因此没有遍历方法、没有 size,不支持 clear()。

proxy

Proxy 用于修改操做(getset)的默认行为
说到这里是否是想到了 Object.defineProperty ?其实也和 JavaBean 那种操做 getter、setter 差很少。

等同于在语言层面作出修改,对编程语言进行编程,属于一种“元编程”(meta programming )。

Proxy 能够理解成,在目标对象以前架设个代理,对该对象的访问,都必须先经过代理,这样能够对外界的访问进行过滤和改写

vue 2.x 基于 Object.defineProperty 来实现的,可是会有一些场景监测不到(array.lenth、$set)。
vue 3.x 使用了 Proxy 来作了,能够监测到更多的场景。固然,基于兼容性考虑仍是能够回退到 Object.defineProperty

var obj = new Proxy({}, {
  get: function (target, propKey, receiver) {
    console.log(`getting ${propKey}!`);
    return Reflect.get(target, propKey, receiver);
  },
  set: function (target, propKey, value, receiver) {
    console.log(`setting ${propKey}!`);
    return Reflect.set(target, propKey, value, receiver);
  }
});

从下面这个例子咱们能够看到,咱们能够只设置读的代理,无论读取什么都返回 www.lilnong.top。而后咱们没有设置写的代理,值已经被真正的写入了。
image.png

构造函数

var proxy = new Proxy(target, handler);

支持代理的操做

key arguments 触发时机 demo
get (target, propKey, receiver) 读取属性时触发 proxy.titleproxy['title']
set (target, propKey, value, receiver) 设置属性时触发 proxy.title = 'lilnong.top'proxy['title'] = 'lilnong.top'
has (target, propKey) in 时触发 title in proxy
deleteProperty (target, propKey) delete时触发 delete proxy.title
ownKeys (target) 获取 key 合集时触发 Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy)for...in
getOwnPropertyDescriptor (target, propKey) 读取属性时触发 Object.getOwnPropertyDescriptor(proxy, propKey)
defineProperty (target, propKey, propDesc) 读取属性时触发 Object.defineProperty(proxy, propKey, propDesc)Object.defineProperties(proxy, propDescs)
preventExtensions (target) 读取属性时触发 Object.preventExtensions(proxy)
getPrototypeOf (target) 读取属性时触发 Object.getPrototypeOf(proxy)
isExtensible (target) 读取属性时触发 Object.isExtensible(proxy)
setPrototypeOf (target, proto) 读取属性时触发 Object.setPrototypeOf(proxy, proto)
apply (target, object, args) proxy 为函数被调用时触发 proxy(...args)proxy.call(object, ...args)proxy.apply(...)
construct (target, object, args) proxy 为实例被New 时触发 new proxy(...args))

注意事项

  1. 严格模式下,set 代理执行完毕应该返回 true,不然会报错。

symbol

ES5 的 对象属性名都是字符串,这容易形成属性名的冲突。好比,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。若是有一种机制,保证每一个属性的名字都是独一无二的就行了,这样就从根本上防止属性名的冲突。这就是 ES6 引入 Symbol的缘由。

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

Symbol 值经过 Symbol 函数生成。这就是说,对象的属性名如今能够有两种类型,一种是原来就有的字符串,另外一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,能够保证不会与其余属性名产生冲突。

s = Symbol();
typeof s // "symbol"

s1 = Symbol('foo');
s1 // Symbol(foo)
s1.toString() // "Symbol(foo)"

s2 = Symbol('bar');
s2 // Symbol(bar)
s2.toString() // "Symbol(bar)"

reflect

Reflect对象与Proxy对象同样,也是 ES6 为了操做对象而提供的新 API。

Reflect对象的设计目的有这样几个。

(1) 将Object对象的一些明显属于语言内部的方法(好比Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在ObjectReflect对象上部署,将来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上能够拿到语言内部的方法。

(2) 修改某些Object方法的返回结果,让其变得更合理。好比,Object.defineProperty(obj, name, desc)在没法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false
....
.... https://es6.ruanyifeng.com/#d...

generator

Generator 函数也是 ES6 提供的一种异步编程解决方案。如今通常都是 Promise 或者 await/async,就不展开说了。

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数彻底不一样。本章详细介绍 Generator 函数的语法和 API,它的异步编程应用请看《Generator 函数的异步应用》一章。

Generator 函数有多种理解角度。语法上,首先能够把它理解成,Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,仍是一个遍历器对象生成函数。返回的遍历器对象,能够依次遍历 Generator 函数内部的每个状态。

形式上,Generator 函数是一个普通函数,可是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不一样的内部状态(yield在英语里的意思就是“产出”)。

....
.... https://es6.ruanyifeng.com/#d...

微信公众号:前端linong

clipboard.png

参考文献

  1. 前端培训目录、前端培训规划、前端培训计划
  2. https://developer.mozilla.org/zh-CN/
  3. http://es6.ruanyifeng.com/
相关文章
相关标签/搜索