ES6新语法概览
来源:互联网 发布:艾默生网络能源年终奖 编辑:程序博客网 时间:2024/05/16 23:58
语法
箭头函数、this
ES6中可以使用 => 作为函数表达形式,极简风格,参数+ => +函数体。
// 1.1单行 无参数var foo = function(){return 1}//等价于let foo = () => 1// 1.1单行 有参数var foo = function(x){return x}//等价于let foo = (x) => x// 2.1多行function add(a,b){ console.log(a+b) return a+b}// 等价于let add = (a,b)=>{ console.log(a+b) return a+b}// testlet nums = [1,2,3,5,10]let fives = []nums.forEach(v => { if (v % 5 === 0) fives.push(v)});console.log(fives) //[5,10]
箭头函数中的 this 指的不是window,是对象本身。
function aa(){ this.bb = 1; setTimeout(() => { this.bb++; //this指向aa console.log(this.bb); },500);}aa(); //2
let、const
ES6 推荐在函数中使用 let 定义变量
const 用来声明一个常量,但也并非一成不变的
- let 和 const 只在最近的一个块中(花括号中)有效
var a = 1;{ let a = 2; console.log(a); //2}console.log(a); //1const A = [1,2];A.push = 3;console.log(A); //[1,2,3]A = 10; //Error
Classes
JavaScript语言的传统方法是通过构造函数,定义并生成新对象
Class内部只有静态方法,没有静态属性,但可以用另外方式解决
function Point(x, y) { this.x = x; this.y = y;}Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')';};var p = new Point(1, 2);//这种写法跟传统的面向对象语言(比如C++和Java)差异很大,很容易让新学习这门语言的程序员感到困惑
- ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
//定义类class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; }}//上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。//也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法
test
class Animal { constructor(){ console.log('我是一个动物'); }}class Person extends Animal { constructor(){ super(); console.log('我是一个程序员'); }}let aa = new Person();//我是一个动物//我是一个程序员
解构
解构赋值是ES6中推出的一种高效、简洁的赋值方法
没啥说的,直接上代码:
//通常情况下var first = someArray[0];var second = someArray[1];var third = someArray[2];//解构赋值let [first, second, third] = someArray; //比上面简洁多了吧//还有下面例子let [,,third] = [1,2,3];console.log(third); //3let [first,...last] = [1,2,3];console.log(last); //[2,3]//对象解构let {name,age} = {name: "lisi", age: "20"};console.log(name); //lisiconsole.log(age); //20let {ept} = {};console.log(ept); //undefined
Rest + Spread
“…”
//Restfunction f(x, ...y) { return x * y.length;}f(3, "hello", true) == 6//Spreadfunction f(x, y, z) { return x + y + z;}f(...[1,2,3]) == 6
对象于面量扩展
- 可以在对象字面量里面定义原型
- 定义方法可以不用function关键字
- 直接调用父类方法
//通过对象字面量创建对象var human = { breathe() { console.log('breathing...'); }};var worker = { __proto__: human, //设置此对象的原型为human,相当于继承human company: 'freelancer', work() { console.log('working...'); }};human.breathe();//输出 ‘breathing...’//调用继承来的breathe方法worker.breathe();//输出 ‘breathing...’
模版字符串
ES6中提供了用反引号`来创建字符串,里面可包含${…}等
`This is a pretty little template string.``In ES5 this is not legal.`let name = "Bob", time = "today";`Hello ${name}, how are you ${time}?`
Iterators(迭代器)
ES6 中可以通过 Symbol.iterator
给对象设置默认的遍历器,直到状态为true退出。可以是数组,对象,Set,Map类型的。
var arr = [11,12,13];var itr = arr[Symbol.iterator]();itr.next(); //{ value: 11, done: false }itr.next(); //{ value: 12, done: false }itr.next(); //{ value: 13, done: false }itr.next(); //{ value: undefined, done: true }// 循环输出,该循环速度快for(;;){ let elem = itr.next() if(elem.done){ break } console.log(elem.value)}
Generators
Generators函数是ES6新增的一种异步编程方案。是一种新的语法结构,一个遍历器对象生成器,它内部可以封装多个状态,非常适合异步操作。
Generators函数语法和普通的function函数类似,但是有三个不同点:
- (1)function关键字和函数名称之间有一个星号(*)
- (2)函数体内可以使用yieId语句
- (3)函数调用后不会立即执行,返回的是一个遍历器对象
Run-Stop-Run…
// 1.function *foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z);}var it = foo( 5 );console.log( it.next() ); // { value:6, done:false }console.log( it.next( 12 ) ); // { value:8, done:false }console.log( it.next( 13 ) ); // { value:42, done:true }// 2.// 一个Generators函数function *yuanku(){ yieId "冤苦", yieId "冤苦", yieId "冤苦", return "end"}// 函数内部使用yieId语句定义不同状态,return也可以定义一个状态,也就是说上面代码有四个状态var y = yuanku() // 调用此函数,并不会立即执行它其中的代码,而是返回一个遍历器对象console.log(y.next()) // 返回一个具有value和done属性的对象console.log(y.next()) // youreturn,返回(value:end,done:true);如果没有return,返回(value:undefined,done:true)// yieId语句// 每一个yieId语句定义不同的状态,它也是一个代码执行暂停标识//yieId语句不能在普通函数中使用,否则会报错// 调用Generators函数可以返回一个遍历器对象,要想访问Generators函数中的每一个状态,需要使用遍历器对象调用next()方法// 如果使用yieId语句作为其他语句的额一部分,那么必须使用小括号包裹,否则会报错。例如:function *yuanku(){ //console.log("欢迎来到"+yieId"冤苦") // 报错 console.log("欢迎来到"+(yieId"冤苦"))// 正确}let y = yuanku()console.log(y.next().value) // 先返回yieIdconsole.log(y.next().value) // 再返回return,yieId为undefined
generator能实现好多功能,如配合for…of使用,实现异步等等,我在这里就不多说了。
for…of && for…in
- for…of 遍历(数组)
let arr = [1,2,3];for (let itr of arr) { console.log(itr); //1 2 3}
- for…in 遍历(对象中的属性)
let arr = [1,2,3];arr.aa = 'bb';for (let itr in arr) { console.log(itr); //0 1 2 aa}
Map + Set + WeakMap + WeakSet
Set 对象是一组不重复的值,重复的值将被忽略,值类型可以是原始类型和引用类型
WeakSet是一种弱引用(垃圾自动回收,防止内存泄漏),只用于对象。同理WeakMap(键名只接受对象)
// Setsvar s = new Set();s.add("hello").add("goodbye").add("hello");s.size === 2;s.has("hello") === true;// Mapsvar m = new Map();m.set("hello", 42);m.set(s, 34);m.get(s) == 34;// Weak Mapsvar wm = new WeakMap();wm.set(s, { extra: 42 });wm.size === undefined// Weak Setsvar ws = new WeakSet();ws.add({ data: 42 });
Proxies
Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”
//定义被侦听的目标对象var engineer = { name: 'Joe Sixpack', salary: 50 };//定义处理程序var interceptor = { set: function (receiver, property, value) { console.log(property, 'is changed to', value); receiver[property] = value; }};//创建代理以进行侦听engineer = Proxy(engineer, interceptor);//做一些改动来触发代理engineer.salary = 60; //控制台输出:salary is changed to 60
Symbols
ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引入Symbol的原因。
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)
Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型
Symbol 是一种新的字符串数据类型,它的值是唯一的,不可变的。
- ES6 中提出 symbol 的目的是为了生成一个唯一的标识符,不过你访问不到这个标识符.
1、类型
let s = Symbol();typeof s// "symbol"
- 上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是Symbol数据类型,而不是字符串之类的其他类型
- 注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。也就是说,由于Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型
2、 如果 Symbol 的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个 Symbol 值
var s1 = Symbol('foo');var s2 = Symbol('bar');s1 // Symbol(foo)s2 // Symbol(bar)s1.toString() // "Symbol(foo)"s2.toString() // "Symbol(bar)"
注意,Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。
3 、没有参数的情况
var s1 = Symbol();var s2 = Symbol();s1 === s2 // false
4、有参数的情况
var s1 = Symbol('foo');var s2 = Symbol('foo');s1 === s2 // false
上面代码中,s1和s2都是Symbol函数的返回值,而且参数相同,但是它们是不相等的
5、Symbol值不能与其他类型的值进行运算,会报错
var sym = Symbol('My symbol');"your symbol is " + sym// TypeError: can't convert symbol to string`your symbol is ${sym}`// TypeError: can't convert symbol to string
6、但是,Symbol值可以显式转为字符串。
var sym = Symbol('My symbol');String(sym) // 'Symbol(My symbol)'sym.toString() // 'Symbol(My symbol)'
8、另外,Symbol值也可以转为布尔值,但是不能转为数值。
var sym = Symbol();Boolean(sym) // true!sym // falseif (sym) { // ...}Number(sym) // TypeErrorsym + 2 // TypeError
- 如果要获取对象 symbol 属性,需要使用
Object.getOwnPropertySymbols(o)
Promises
ES6 对 Promise 有了原生的支持,一个 Promise 是一个等待被异步执行的对象,当它执行完成后,其状态会变成 resolved 或者 rejected
Promises对象具有三种状态:Pending(等待)、Resolved(已完成)、Rejected(未完成)
Promises对象状态的改变只有两种可能:Pending转变为Resolved,或者Pending转变为Rejected
Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的 deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式
function timeout(duration = 0) { return new Promise((resolve, reject) => { setTimeout(resolve, duration); })}var p = timeout(1000).then(() => { return timeout(2000);}).then(() => { throw new Error("hmm");}).catch(err => { return Promise.all([timeout(100), timeout(200)]);})
想要了解promise实际应用等,详见。
小结
总之,ES6还是有很多棒棒的语法,有利于精简代码,高效开发;只不过一些低级别浏览器不支持,可以用Babel等工具把ES6转化成ES5
- ES6新语法概览
- ES6新语法概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- es6新特性概览
- ES6新特性概览
- c#中Class和Struct使用与性能的区别
- Eclipse使用hibernate进行HQL语句查询时,速度慢的原因之一
- 大屏可视化助力大数据应用落地
- python学习笔记(装饰器)
- 判断字典中的值是否为空
- ES6新语法概览
- boundingRect 输入点返回最小矩形
- sso 单点登录
- mysql 优化(五)
- 1 Ubuntu系统下的caffe安装与配置
- RMAN多种备份脚本分享
- 高通安卓分区
- mysql导出.sql脚本
- groupby查询分组后按条件查询所需要的记录