es678910语法糖
傲娇:
新es是js的进步,是编程的进步,es6已经过去了5年了,兼容率达到了90%,还是有10%的手机不兼容,那到底应不应该去照顾那些跟不上的人,我觉得是不应该的,新es能5行写出来的功能,我为什么要用旧的写50行,还那么难理解,难维护,但我还是兼容了,人在屋檐下,不得不低头
Label是es向下兼容的工具,这个在node分类下提及,这里不说
所有的内容都来自 阮一峰大神的博客
2019年11月09日中午12点,博客里的内容从【0前言到31参考链接】
经常用的api有
- let和const
- 解构赋值 和 拓展运算符
- 字符串拓展
- 数字的拓展
- 函数的拓展 和 拓展运算符
- 数组的拓展 和 Iterator
- 对象的拓展
- 新类型Set 和 Iterator
- 新类型Map 和 Iterator
- Reflect
- Proxy观察者
- Promise
- async
- class
- module
let和const
- let代替了var,let没有变量提升,也可以理解为解析js代码流程中,遇到let会自动跳过,在执行过程中才能识别
- const不是变量,而是固定常亮,如果是基础数据类型第一次赋值后不能被修改值,如果是复杂数据类型,可以修改内部的内容,但是不能修改数据类型,而且一个函数作用域里只能声明一次,也就是不能声明两次aa,会报错,能保护这个值不轻易被另一个程序员重新声明或者改了
还有些详细内容放在下一篇写
解构赋值
解构赋值分为数组解构和对象解构
数组解构,是按顺序来的,并且左边用数组解构,右边一定要是数组
// 基础应用
// 可以理解为右边的数组是ajax请求来的res
let [a, b, c] = [1, 2, 3];
console.log(a,b,c)
// 跳过使用
let [ , , c] = ["foo", "bar", "baz"];
console.log(c) // "baz"
// 二级数组
let [a, b, d] = [1, [2, 3], 4];
console.log(b) //[2,3]
// 拓展运算符
// 拓展运算符一次赋值只能用一次,而且只能用在最后一位
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
对象解构
对象解构是用key赋值的,没有顺序
对象解构比数组解构用得多得多
// 基础应用
// 可以理解为右边的数组是ajax请求来的res
let { bar,foo,ceshi} = { foo: 'aaa', bar: 'bbb' };
console.log(bar,foo,ceshi) // 'bbb','aaa',undefined
// 上面的写法其实是对象的省略写法,因为key-value同名所以缩写
// 如果不缩写是 let { bar:bar,foo:foo,ceshi:ceshi} = { foo: 'aaa', bar: 'bbb' };
// 所以不缩写可以重命名
let { bar:newBar,foo:newFoo,ceshi:newCeshi} = { foo: 'aaa', bar: 'bbb' };
console.log(newBar,newFoo,newCeshi) // 'bbb','aaa',undefined
// 默认值
var {x = 1} = {};
console.log(x) //1
// 上面的默认值也是省略写法
var {x:newX = 1} = {x: 5};
console.log(newX) //5
//清除对象里不要的key
let {_internal, tooBig, ...cleanObject} = {el1: '1', _internal:"secret", tooBig:{}, el2: '2', el3: '3'};
console.log(cleanObject); // {el1: '1', el2: '2', el3: '3'}
字符串拓展
上代码自己理解
var basket = {
count: 10,
onSale: "aa"
}
// 原先的字符串拼接
$('#result').append(
'There are <b>' + basket.count + '</b> ' +
'items in your basket, ' +
'<em>' + basket.onSale +
'</em> are on sale!'
);
// 新版的字符串拼接,两端是``斜点
// 数据是${...},
// 可以用默认值 ${ name || "pdt" }
// 可以用简单的方法${ time2date(time) }
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
数字的拓展
之前把字符串转数字用的是减零
Number("123")
// 转不了的就是NaN
Number("123a") //NaN
函数的拓展
有参数默认值,参数解构,参数拓展运算符,箭头函数
// 参数默认值
// 以往的参数默认值是这样的
function init(name){
var name = name || "pdt"
}
// es6可以
function init(name = "pdt"){ ... }
// 参数解构
// 老版本
function init(arr,obj){ ... }
init([1,2],{name:"pdt",age:18})
// 新写法
function init([,b],{name="无名"}){
//比如我只需要数组的第二个和name属性
console.log(a,b,name)
}
init([1,2],{name:"pdt",age:18})
//参数必填
const required = () => {throw new Error('Missing parameter')};
const add = (a = required(), b = required()) => a + b;
add(1, 2) //3
// 箭头函数,是function的缩写
// 但是不能作为对象的value,不能作为数组的值,不能作为构造函数
// 箭头函数没有自己的this
// 箭头函数没有三个改变this的方法
// 箭头函数没有arguments
// 声明
var init = () => { ... }
// 作为参数
function init(cb){
cb(111)
}
// 旧版
init(function(num){ console.log(num )})
// 箭头函数
init((num)=>{ console.log(num })
箭头函数是用来留住this的,具体查看下一篇
数组的拓展
新es给给数组增加了一个叫Iterator
的东西,这个查看《遍历总结》
新增了大量的遍历方式,这个查看《遍历总结》
还有拓展运算符代替function的apply方法(apply是什么查看《上下文和作用域》)
// ES5取数组的最大值
Math.max.apply(null, [14, 3, 77])
// ES6取数组的最大值
Math.max(...[14, 3, 77])
// ES5合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6合并数组
[...arr1, ...arr2, ...arr3]
// ES5把伪数组转成数组
Array.prototype.slice.apply(null,ArrayLike)
// ES6把伪数组转成数组
[...ArrayLike]
// 或者新api
Array.from(ArrayLike)
// ES5查看是否含有,返回第一个出现的位置,没有是-1
arr.indexOf("xx")
// ES6查看是否含有,返回true/false
arr.include("xx")
对象的扩展
// 最后一个key-value可以加逗号了
var obj = {
name: "name",
age: 18, //以前这里结束加逗号是不行的
}
// key-value同名可以省略
// 比如要ajax传个参数
var name = "name",age = 18;
ajax({
// 以前
// data:{ name: name, age: gae }
// 现在可以
data:{name,age}
})
// 对象的value是function的写法优化
// 老写法
var obj = {
say: function(){ ... }
}
// 新写法
var obj = {
say(){ ... }
}
// 对象的遍历,查看《遍历的总结》
// 增加可Obj.vaules() 和 Object.entries()
// 对象的合并assign,这个api是浅拷贝
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
// 也可以
let target = {...target, ...source1}
新类型Set【集合】
Set跟数组差不多,同样是一个畸形的对象
他会自动去重,但只能去重基础数据类型
// 需要通过new去创建,参数是一个数组或者伪数组
let set = new Set([undefined,undefined,NaN,NaN,"",""]); // set{"undefined",NaN,""}
// set的长度属性
set.size //3
// 添加某个值,返回set本身,所以可以无限add()
set.add(value)
// 删除某个值,返回一个布尔值,表示删除是否成功
set.delete(value)
// 返回一个布尔值,表示该值是否为Set的成员
set.has(value)
// 清除所有成员,没有返回值
set.clear()
// Set没有办法取值,只能转数组再取值
[...set]
// 或者
Array.from(set)
// Set的遍历,set.keys(),set.values(),set.entries()
// 具体查看《遍历总结》
// 还有一个WeakSet,不重要
// 他跟Set一样,只是他只能存对象,并且带有垃圾回收功能,面试题来着
const ws = new WeakSet();
集合的几个特性
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));//ES6
var intersect = new Set([...a].filter(function(x){
return b.has(x);
}))
// set {2, 3}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
新类型Map【字典】
Map 结构提供了value-value的对应,相比于Object,他的key可以是任一类型
// 通过new创建,参数是一个数组,数组里的值必须都是两个长度的数组
const map = new Map([
['name', '张三'],
['title', 'Author']
]);
// map的长度属性
map.size // 2
// 添加某个值,返回set本身,所以可以无限add()
map.set(key, value)
// 返回一个布尔值,表示该值是否为Set的成员
set.has(key)
//
map.get(key)
// 删除某个值,返回一个布尔值,表示删除是否成功
map.delete(key)
// 清除所有成员,没有返回值
map.clear()
// Map的遍历,map.keys(),map.values(),map.entries()
// 具体查看《遍历总结》
// Map转数组,其实map挺好用的,没必要转,除非是要传给后端
[...map]
// 还有一个WeakMap,不重要
// 只接受对象作为键名(null除外),不接受其他类型的值作为键名
const wm = new WeakMap();
其实Set和Map也非常的稀有,因为数组和对象就已经很好用了,而且还要去兼容,而且还要去转格式转来转去的
Reflect
Reflect是ES6为了操作对象而新增的API,配合proxy对数据进行操作简直完美
Reflect.get(target, name, receiver)
Reflect.set(target,name,value,receiver)
Reflect.apply(target,thisArg,args)
Reflect.construct(target,args[, newTarget])
Reflect.defineProperty(target,name,desc)
Reflect.deleteProperty(target,name)
Reflect.has(target,name)
Reflect.ownKeys(target)
Reflect.preventExtensions(target)
Reflect.isExtensible(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)
Proxy观察者
这个一般来说是用不到的,是属于架构层面的api了,Vue3.0就是以这个为基础架构的,跟Object.defineProperty一样,这个放在《vue的原理设计》说
// 贴个基础代码
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
Promise
查看《promise篇》
Promise里装的都应该是异步函数,如果是同步的反而是产生BUG
// 贴个基础代码
new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
}).then((value)=>{ ... },(error)=>{ ... })
Async
查看《promise篇》
await后面跟着的都是promise异步函数,如果是同步的反而是产生BUG
// 贴个基础代码
async function main() {
try {
const val1 = await firstStep();
const val2 = await secondStep(val1);
const val3 = await thirdStep(val1, val2);
console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
class
查看《class》篇
class就是一个新型的构造函数
// 贴个基础代码
class A {
constructor(name) {
// 静态属性/方法
this.name = name;
}
// 相当于原型方法,class不支持原型属性
print() {
console.log(this.name);
}
// 带有static是私有方法/属性,通过A.myMethod()执行
static myMethod() {
console.log('static');
}
}
class B extends A {
constructor(name,age) {
//继承的
super();
this.name = name;
this.age= age;
}
m() {
console.log(this.age);
}
}
let b = new B("pdt",18);
b.m() // 18
b.print() // "pdt"
module
查看《模块化》篇
引入js文件的新api但是不被支持,浏览器没支持连nodejs都没支持
// 开放多个,只能全是export,不能有export default
// fs.js
export function A(){ ... }
export B = { ... }
export C = []
export D = "D"
// 引入并且解构赋值
import { A, B, C, D } from 'fs';
// 只能出现一个export default,并且不能有其他export
// default就不需要名字了
// fs.js
export default function(){ ... }
// 或者对象,其他格式都行
export default {}
// 引入并且解构赋值
import fs from 'fs';
除了上面常用的
还有Symbol,Decorator【装饰器】
- Method Decorator 函数装饰器
- Property Decorators 熟悉装饰器
- Class Decorator 类装饰器
- Parameter Decorator 参数装饰器
将来装饰器会变成新的框架,会被制造出像Spring
的框架
说几句
这些api升级了js的难度,生产出了大量的玩法和框架,他让前端不再是个jq打天下的菜鸡,他需要学的东西越来越多,这些api高仿自很多的语言,特别是java
比如说拓展运算符,Iterator遍历器,Set,Map,await的原生就是一个yeild,这个也是java的,还有class,model的import,Decorator就是java的注解以及NodeJs的stream流等等
es678910语法糖的更多相关文章
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- C#语法糖大汇总
首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...
- 看看C# 6.0中那些语法糖都干了些什么(终结篇)
终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...
- 看看C# 6.0中那些语法糖都干了些什么(中篇)
接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点 叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲. 一:字符串嵌入值 我想 ...
- 看看C# 6.0中那些语法糖都干了些什么(上篇)
今天没事,就下了个vs2015 preview,前段时间园子里面也在热炒这些新的语法糖,这里我们就来看看到底都会生成些什么样的IL? 一:自动初始化属性 确实这个比之前的版本简化了一下,不过你肯定很好 ...
- C# 6.0新特性---语法糖
转载:http://www.cnblogs.com/TianFang/p/3928172.html 所谓语法糖就是在编译器里写做文章,达到简化代码书写的目的,要慎重使用,省略过多不易理解. NULL检 ...
- C#语法糖,让编程更具乐趣
一.什么是语法糖 语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法 ...
- Java语法糖4:内部类
内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...
- Java语法糖1:可变长度参数以及foreach循环原理
语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...
随机推荐
- mysql字符串相关函数(并与sql server对比)
https://blog.csdn.net/zhengxiuchen86/article/details/81220779 1.判断子串substr在字符串str中出现的位置 例子:查询']'在‘OP ...
- swiper插件遇到的坑
1.网速卡的情况下轮播图会出现塌陷 解决方法: 在swiper外层固定高度,用填充百分比方法: html代码:在swiper-container加一层外层,外层用padding-top:50%(看图片 ...
- lua叠代器
注意:叠待值遇到nil就退出 叠代器,是符合for遍历框架,需要满足条件 1-叠代函数,常量,控制变量 2-叠代函数可以接受二个参数,当然也可以忽略处理(利用闭包封装参数作为控制变量和状态变量) 无状 ...
- Python基础-3 输入输出
输入输出 input输入函数 input函数:获取用户输入,保存成一个字符串.重要的话,说两遍,input函数的返回值是一个字符串类型.哪怕你输入的是个数字1,返回给你的只会是字符串"1&q ...
- c++模板(翁恺c++公开课[34-35]学习笔记)
为什么要有模板(templates):当我们需要一个列表(list),列表中元素可能都为X类型也可能都为Y类型,怎么来实现呢? 定义基类?可以实现,很多情况下可能不够简明的表达设计思想 克隆代码(写一 ...
- LeetCode 445. Add Two Numbers II(链表求和)
题意:两个非空链表求和,这两个链表所表示的数字没有前导零,要求不能修改原链表,如反转链表. 分析:用stack分别存两个链表的数字,然后从低位开始边求和边重新构造链表. Input: (7 -> ...
- 【PAT甲级】1023 Have Fun with Numbers (20 分)
题意: 输入一个不超过20位的正整数,问乘2以后是否和之前的数组排列相同(数字种类和出现的个数不变),输出Yes或No,并输出乘2后的数字. AAAAAccepted code: #define HA ...
- arduino#呼吸灯
; // 使用引脚号 void setup() { // nothing happens in setup } void loop() { // fade in from min to max in ...
- 反射工具类【ReflectionUtils】
反射工具类[ReflectionUtils] 原创 2017年05月05日 00:45:43 标签: java / 反射 / reflection / 893 编辑 删除 import java.la ...
- iOS应用的语言设置
首先需要明确两个名词的区别:“当前手机的系统语言”.“应用内部的语言设置” 要解决的问题的情景: 在iOS应用中,有时候会调用系统的一些UI控件,例如: 1.在UIWebView中长按会弹出系统的上下 ...