前端最基础的就是 HTML+CSS+Javascript
。掌握了这三门技术就算入门,但也仅仅是入门,如今前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS
),本着提高技术水平,打牢基础知识的中心思想,咱们开课啦(每周四)。javascript
这节标题超长了,难受箭头函数、set、map、proxy、symbol、reflect、generator前端
以前声明函数使用 function funName(arg1,...args){return args}
。
ES6 增长了新的声明函数方式 (arg1,...args)=>args
。vue
简洁。[1,2,3,4,0,-1,-2,-3].map(v=>Math.sign(v))
java
...
)、解构({status, response}
)都须要加括号。return
。若是有花括号,就须要显式的return
,固然也能够不写默认 return
是 undefined
。this 指向。es6
this
对象指向定义时所在的对象,而不是使用时所在的对象。this
对象是不可变的。bind、call、apply、赋值等操做都没法改变。arguments
。Generator
函数。不可使用 yield
命令不该该在声明对象的时候使用。由于这个时候里面的 this
指向定义时的环境。编程
obj = { name: 'app', jumps: () => { console.log(this.app); } }
Set
特色是值惟一和有序。相似于数组,可是成员的值都是惟一的,没有重复的值,遍历的话是插入顺序。Array.from(new Set([1,2,3,1,1,2,3,1]))
依赖值惟一的特性实现去重。segmentfault
new Set([iterable]);
使用可迭代的数组来建立。数组
new Set([1,2,3,4,2,1,1,1,12,3])
new Set('123123')
new Set(['123123',1,2,3])
new Set(document.querySelectorAll('a'))
Set.prototype.size
:返回总数,等价于(Array.prototype.length
)Set.prototype.add(value)
:添加,返回当前对象可链式操做。Set.prototype.delete(value)
:删除,返回一个布尔值,表示删除是否成功。Set.prototype.has(value)
:返回一个布尔值,表示该值是否为Set的成员。Set.prototype.clear()
:清除全部成员,没有返回值。Set.prototype.keys()
:返回键(key)的遍历器 Iterator。Set.prototype.values()
:返回值(value)的遍历器 Iterator。Set.prototype.entries()
:返回键值对([key, value])的遍历器 Iterator。Set.prototype.forEach()
:使用回调函数(value, key, this)=>遍历每一个成员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)
map = new Map([ ['key1', 'value1'], ['key2', 'value2'] ]); map.forEach( (key, value) => console.log(key, value) );
size
返回记录总数。(Object
但是没有这个属性的哟)set(key, value)
赋值操做get(key)
取值操做has(key)
判断当前 key
是否存在于集合中。delete(key)
删除操做。返回 true
,代表删除成功。返回 false
代表删除失败,好比你删除了一个不存在的 key
。clear()
清空全部。遍历方法。(插入顺序)
Map.prototype.keys()
:返回键名的遍历器。Map.prototype.values()
:返回键值的遍历器。Map.prototype.entries()
:返回全部成员的遍历器。Map.prototype.forEach()
:遍历 Map 的全部成员。WeakMap
只接受对象做为键名(null
除外),不接受其余类型的值做为键名。WeakMap
的键名所指向的对象,不计入垃圾回收机制。
由于是弱引用,因此没有遍历方法、没有 size,不支持 clear()。
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
。而后咱们没有设置写的代理,值已经被真正的写入了。
var proxy = new Proxy(target, handler);
key | arguments | 触发时机 | demo |
---|---|---|---|
get |
(target, propKey, receiver) |
读取属性时触发 | proxy.title 和 proxy['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)) |
set
代理执行完毕应该返回 true
,不然会报错。ES5 的 对象属性名都是字符串,这容易形成属性名的冲突。好比,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。若是有一种机制,保证每一个属性的名字都是独一无二的就行了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol
的缘由。ES6 引入了一种新的原始数据类型
Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(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
对象与Proxy
对象同样,也是 ES6 为了操做对象而提供的新 API。
Reflect
对象的设计目的有这样几个。(1) 将
Object
对象的一些明显属于语言内部的方法(好比Object.defineProperty
),放到Reflect
对象上。现阶段,某些方法同时在Object
和Reflect
对象上部署,将来的新方法将只部署在Reflect
对象上。也就是说,从Reflect
对象上能够拿到语言内部的方法。(2) 修改某些
Object
方法的返回结果,让其变得更合理。好比,Object.defineProperty(obj, name, desc)
在没法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)
则会返回false
。
....
.... https://es6.ruanyifeng.com/#d...
Generator
函数也是 ES6 提供的一种异步编程解决方案。如今通常都是 Promise
或者 await/async
,就不展开说了。
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数彻底不一样。本章详细介绍 Generator 函数的语法和 API,它的异步编程应用请看《Generator 函数的异步应用》一章。Generator 函数有多种理解角度。语法上,首先能够把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,仍是一个遍历器对象生成函数。返回的遍历器对象,能够依次遍历 Generator 函数内部的每个状态。
形式上,Generator 函数是一个普通函数,可是有两个特征。一是,
function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
表达式,定义不一样的内部状态(yield
在英语里的意思就是“产出”)。....
.... https://es6.ruanyifeng.com/#d...