最基础的前端就是HTML+CSS+Javascript。掌握这三项技术算是入门,但也只是入门而已。现在前端开发的定义远不止于此。前端小课堂(HTML/CSS/JS),本着提高技术水平,夯实基础知识的中心思想,开课(每周四)。前言这段BB的标题太长了。使用函数funName(arg1,...args){returnargs}很难在箭头函数、set、map、proxy、symbol、reflect和生成器箭头函数之前声明函数。ES6添加了一种声明函数的新方法(arg1,...args)=>args。箭头函数具有匿名函数。从上面的例子可以看出,匿名函数是没有名字的。用法等同于前面的函数表达式。简洁的。[1,2,3,4,0,-1,-2,-3].map(v=>Math.sign(v))输入参数省略。如果只有一个输入参数,括号可以省略。无入参、多入参、rest参数(...)、解构({status,response})需要括号。函数体的省略。如果没有花括号,则只能传入一个表达式,返回表达式的结果。如果有花括号,则需要显式返回。当然没必要写默认returnisundefined。这指向。箭头函数的this对象指向定义它的对象,而不是使用它的对象。箭头函数的this对象是不可变的。bind、call、apply、assignment等操作不能改变。不能用作构造函数。因为上面这个问题。没有争论。不能用作生成器函数。不要使用yield命令声明对象时不应使用箭头函数的一些错误用法。因为此时this里面指向的是定义时的环境。obj={name:'app',jumps:()=>{console.log(this.app);}}Set和WeakSetSet的特点是值的唯一性和有序性。类似于数组,但是成员的值是唯一的,没有重复值,插入顺序就是遍历时的插入顺序。Array.from(newSet([1,2,3,1,1,2,3,1]))依靠值的独特特性来实现去重。设置构造函数newSet([iterable]);使用可迭代数组创建。新集([1,2,3,4,2,1,1,1,12,3])新集('123123')新集(['123123',1,2,3])新集(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)的迭代器。Set.prototype.values():Iterator返回值(value)的迭代器。Set.prototype.entries():返回一个键值对([key,value])的迭代器。Set.prototype.forEach():使用回调函数(value,key,this)=>遍历每个成员WeakSet只能存储对象的集合,通过弱引用保存。弱引用是可以被垃圾回收的(如果你把它们放在一个数组中,那么你不知道真正可以回收的是什么,因为数组是强引用),没有不能枚举的总数。Map和WeakMapMap其实和JavaScript对象(Object)一样,本质上都是键值对(Hash结构)的集合。但是传统上Object只能使用字符串作为key,使用上有很大的局限性。Map的数据结构也可以理解为一个对象,它是键值对的集合。但是key的范围不限于字符串,其他类型(包括对象)都可以作为key。是比较完整的Hash结构实现。userinfo={name:'lilnong.top'}map=newMap()map.set(userinfo,{age:123})map.has(userinfo)map.get(userinfo)构造函数map=newMap([['key1','value1'],['key2','value2']]);map.forEach((key,value)=>console.log(key,value));属性和方法size返回记录总数。(对象没有这个属性)set(key,value)赋值操作get(key)value操作has(key)判断当前key是否存在于集合中。delete(key)删除操作。返回true,表示删除成功。返回false表示删除失败,比如你删除了一个不存在的key。clear()清除所有。遍历法。(插入顺序)Map.prototype.keys():返回一个键名的遍历器。Map.prototype.values():返回键值的迭代器。Map.prototype.entries():返回所有成员的遍历器。Map.prototype.forEach():遍历Map的所有成员。weakMapWeakMap只接受对象作为键(null除外),不接受其他类型的值作为键。WeakMap的键名指向的对象不计入垃圾回收机制。因为是弱引用,没有遍历方法,没有大小,不支持clear()。proxyProxy用于修改操作(getset)的默认行为。说到这里,是不是想到了Object.defineProperty?其实类似于JavaBean的操作getter和setter。相当于在语言层面进行修改,编程语言编程是一种“元编程”。Proxy可以理解为在目标对象之前设置一个代理,对对象的访问必须先经过代理,这样才能对外部访问进行过滤和重写。Vue2.x是基于Object.defineProperty实现的,但是有一些场景无法检测到(array.lenth,$set)。Vue3.x使用Proxy来监控更多的场景。当然,出于兼容性原因,您仍然可以回退到Object.defineProperty。varobj=newProxy({},{get:function(target,propKey,receiver){console.log(`getting${propKey}!`);returnReflect.get(target,propKey,receiver);},set:function(target,propKey,value,receiver){console.log(`setting${propKey}!`);returnReflect.set(target,propKey,value,receiver);}});从下面的例子我们可以看到,我们只要设置阅读的代理,无论阅读什么都返回www.lilnong.top。然后我们没有设置写入的代理,值实际上已经被写入了。构造函数varproxy=newProxy(target,handler);支持代理操作keyarguments触发时序demoget(target,propKey,receiver)触发proxy.title和proxy['title']set(target,propKey,value)当读取属性时触发,receiver)当proxy.title='lilnong.top'时触发或proxy['title']='lilnong.top'has(target,propKey)intitleinproxydeleteProperty(target,propKey)deletetriggerswhendeleteproxy.titleownKeys(target)触发Object.getOwnPropertyNames(proxy),Object.getOwnPropertySymbols(proxy),Object.keys(proxy),for...ingetOwnPropertyDescriptor(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)读取属性时触发.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是实例beingnewtriggernewproxy(...args))注意事项在严格模式下,setproxy执行完要返回true,否则会报错。symbolES5的对象属性名都是字符串,容易造成属性名冲突。比如你使用了别人提供的一个对象,但是想给这个对象添加一个新的方法(mixin方式),那么新方法的名字可能会和已有的方法冲突。如果有一种机制可以保证每个属性的名称是唯一的,从而从根本上防止属性名称冲突,那就太好了。这就是ES6引入Symbol的原因。ES6引入了一种新的原始数据类型Symbol,代表一个唯一的值。它是JavaScript语言的第七种数据类型,前六种分别是:undefined、null、布尔(Boolean)、字符串(String)、值(Number)、对象(Object)。Symbol值由Symbol函数生成。也就是说,对象的属性名现在可以有两种类型,一种是原来的字符串,一种是新加的Symbol类型。所有属于Symbol类型的属性名都是唯一的,可以保证不与其他属性名冲突。s=Symbol();typeofs//"symbol"s1=Symbol('foo');s1//Symbol(foo)s1.toString()//"Symbol(foo)"s2=Symbol('bar');s2//Symbol(bar)s2.toString()//"Symbol(bar)"reflectReflect对象和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...generatorGenerator函数也是ES6提供的异步编程解决方案。现在一般是Promise或者await/async,就不说了。生成器函数是ES6提供的一种异步编程解决方案,其语法行为与传统函数完全不同。本章详细介绍了Generator函数的语法和API。其异步编程应用请参考《Generator 函数的异步应用》章节。对Generator函数的理解有很多角度。从语法上,首先可以理解为Generator函数是一个封装了多个内部状态的状态机。执行Generator函数会返回一个遍历器对象,也就是说Generator函数不仅是一个状态机,还是一个遍历器对象生成函数。返回的遍历器对象可以依次遍历Generator函数内部的各个状态。形式上,Generator函数是一个普通函数,但具有两个特征。一种是函数关键字和函数名之间有一个星号;另一种是在函数体内使用yield表达式来定义不同的内部状态(yield在英文中是“输出”的意思)。......https://es6.ruanyifeng.com/#d...微信公众号:前端力农参考前端培训目录,前端培训规划,前端培训计划https://developer.mozilla.org/zh-CN/http://es6.ruanyifeng.com/
