ESMAScript6简介,ES6是JavaScript语言的下一代标准,目的是让JavaScript语言能够写复杂的大型应用程序,成为企业级语言。那么ECMAScript和JavaScript的关系究竟是什么呢?二者有着什么样的联系?前端
JavaScript的创造者Netscape公司,将JavaScript提交给国际标准化组织ECMA,但愿这种语言能够成为国际标准,次年,ECMA决定了浏览器脚本语言的标准,并称为ECMAScript。es6
因某些缘由,一是商标,二是这门语言制定者是ECMA,不是Netscape。ECMAScript和JavaScript的关系是前者是后者的规格,后者是前者的一种实现。算法
ES6 let和const命令编程
let命令:json
基本用法,ES6新增let命令,用来声明变量,用法相似于var,但所声明的变量,只在let命令所在的代码块内有效。设计模式
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined b // 1
let和var声明了两个变量,而后在代码块以外调用这两个变量,结果let声明的变量报了错,var声明的变量返回了正确的值。说明,let声明的变量只在它所在的代码块有效。数组
for(let i = 0; i<10; i++) { } console.log(i); // ReferenceError: i is not defined
var a = []; for(var i = 0; i<10; i++) { a[i] = function() { console.log(i); }; } a[6](); // 10
使用let,声明的变量仅仅在块级做用域内有效:promise
var a = []; for(let i = 0; i<10; i++){ a[i] = function() { console.log(i); }; } a[6](); // 6
变量i是let声明的,当前的i只在本轮循环有效,因此每一次循环的i其实都是一个新的变量,因此最后输出6。浏览器
不存在变量提高安全
var存在变量提高,let不会发生“变量提高”的现象,因此,变量必定要在声明后使用,否则会报错。
console.log(a); // 输出undefined console.log(b); // 报错ReferenceError var a = 1; let b = 1;
var声明的变量会发生变量提高,该变量没用赋值就已经存在了,可是没有值,就会输出undefined,变量用let命令声明,不会发生变量提高,声明变量以前,变量是不存在的,若是用它,就会报错。
用let声明的变量是能够修改的,而用const通常用来声明常量,声明以后不能更改了。
let a = 1; const b = 2; a = 3; b = 3; // 报错
var命令声明的变量会发生变量提高的现象,变量在声明以前使用,其值为undefined,而let命令声明的变量没有变量提高,若是在声明以前使用,会报错的。
暂时性死区,在一个块级做用域中对一个变量使用let声明前,该变量是不可以使用,称为暂时性死区。
da = 'coding'; if(true) { // 在以前就定义 一个全局变量da,块内从新定义了一个da console.log(da); // 报错ReferenceError let da; }
不容许重复声明:
let命令是不容许重复声明同一个变量的
if(true) { let da; let da; // 报错 } function func(coding) { // 已经有个变量名的形参了 let coding; } func() // 报错
在代码块内,使用let命令声明变量以前,该变量都是不可用的,称为暂时性死区。
if(true) { temp = 'da'; // ReferenceError console.log(temp); // ReferenceError let temp; // TDZ结束 console.log(temp); // undefined temp = 12; console.log(temp); // 12 }
暂时性死区代表typeof再也不是一个安全的操做
typeof x; // ReferenceError let x;
变量x使用了let命令声明,因此存在死区,用到该变量就会报错,做为对比,若是一个变量根本没有被声明,使用typeof就不会报错
typeof dacoding // undefined
ES6:
var arr = []; for(var i=0; i<10; i++) { arr.push(function() { console.log(i) }) } arr.forEach(function(func) { func() });
// ES5 var arr = []; for(var i=0; i<10; i++){ func.push((function(value){ return function() { console.log(value); } }(i)) }
// ES6 for(let i = 0; i<10; i++) { func.push(function(){ console.log(i) }) }
箭头函数的特色:不须要function关键字来建立函数,省略return关键字,继承当前上下文的this关键字。
let声明变量和const声明常量,两个都有块级做用域
ES5中没有块级做用域,var有变量提高,在let中,使用的变量必定要进行声明。箭头函数,定义不在使用关键字function(),而是用箭头 ()=> 来表示。模板字符串,是加强版的字符串,用反引号(`)表示,能够看成普通字符串使用,同时能够定义多行字符串。
解构赋值,ES6容许按照必定模式,从数组和对象中提取值,对变量进行赋值,for...of循环能够遍历数组,set和map结构。
set数据结构相似数组同样的,全部的数据都是惟一,没有重复的值,它自己是一个构造函数,class类的继承,ES6中不像ES5中使用原型链实现继承,引入了class概念能够用来继承了
// 基础用法 const da1 = function (参数1, 参数2, …, 参数N) { 函数声明 } const da1 = (参数1, 参数2, …, 参数N) => { 函数声明 } // 当只有一个参数时,圆括号是可选 const da2 = (单一参数) => { 函数声明 } const da2 = 单一参数 => { 函数声明 } // 没有参数时,圆括号不能省略 const da3 = () => { 函数声明 } // 当函数体只是 return 一个单一表达式时,能够省略花括号和 return 关键词 const da4 = () => { return 表达式(单一) } const da4 = () => 表达式(单一) // 函数体返回对象字面表达式时,若是省略花括号和 return 关键词,返回值须要加括号 const da5 = () => { return {foo: 'bar'} } const da5 = () => ({foo: 'bar'}) // 输出 {foo: 'bar'} const da6 = () => {foo: 'bar'} // 输出 undefined,大括号被识别为代码块
块级做用域:
es5只有全局做用域和函数做用域,没有块级做用域:
var temp = new Date(); function f() { console.log(temp); if (false) { var tmp = "hello world"; } } f(); // undefined
es6的块级做用域:
function f1() { let n = 5; if (true) { let n = 10; } console.log(n); // 5 }
// IIFE 写法 (function () { var temp = ...; ... }()); // 块级做用域写法 { let temp = ...; ... }
es5中,函数只能在顶层做用域和函数做用域之中声明,不能在块级做用域中声明。
// 状况一 if (true) { function f() {} } // 状况二 try { function f() {} } catch(e) { } // ES5的规定都是非法的
// ES5严格模式 'use strict'; if (true) { function f() {} } // 报错
在es6中引入了块级做用域,明确容许在块级做用域之中声明函数
// ES6严格模式 'use strict'; if (true) { function f() {} } // 不报错
es6的块级做用域声明函数只在使用大括号的状况下成立
// 不报错 'use strict'; if (true) { function f() {} } // 报错 'use strict'; if (true) function f() {}
箭头函数:
用了箭头函数,this就不是在指向window,而是父级了,不可以使用arguments对象了,不能用构造函数了,就是不能使用new命令了,不然会报错,不能使用yield命令,因此箭头函数不能用做Generator函数了。
map和set的区别:
set用于数据重组,map用于数据储存
set中元素不能重复,只有键值没有键名,相似数组,能够遍历,有方法add,delete,has等。
map的本质是键值对的集合,能够遍历,能够跟各类数据转换。
class类的出现:
//定义类 class Point { constructor(x,y) { //构造方法 this.x = x; //this关键字表明实例对象 this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } }
promise构造函数是同步执行的,then方法是异步执行的。
function Person(){ this.age = 10; setInterval(() => { this.age++; // this 正确地指向 p 实例 }, 100); } var p = new Person(); // 1s后打印出 10
this.param = 1 const func1 = () => console.log(this.param) const func2 = function() { console.log(this.param) } func1.apply({ param: 2 }) // 输出: 1 func2.apply({ param: 2 }) // 输出: 2
解构赋值:
let [a, b, c] = [1, 2, 3] // a:1 b:2 c:3 let [a, [[b], c]] = [1, [[2], 3]] // a:1 b:2 c:3 let [a, , b] = [1, 2, 3] // a:1 b:3 let [a,...b] = [1, 2, 3] // a:1 b:[2, 3] let [a, b,...c] = [1] // a:1 b:undefined c:[] let [a, b = 4] = [null, undefined] // a:null b:4 let [a, b = 4] = [1] // a:1 b:4 let [a, b = 4] = [1, null] // a:1 b:null
解构不成功的,其变量的值为undefined,解构指定默认值,若是该被解构变量的对应位置没有值,为空或者是undefined,默认值才有效。
let { a, b } = { a: 1, b: 2 } // a:1 b:2 let { c } = { a: 1, b: 2 } // c:undefined let { c = 4 } = { a: 1, b: 2 } // c:4 let { a: c } = { a: 1, b: 2 } // c:1 let { a: c = 4, d: e = 5 } = { a: 1, b: 2 } // c:1 e:5 let { length } = [1, 2] // length:2
扩展运算符:
将一个数组转化为逗号分隔的参数序列
console.log(...[1, 2, 3]) // 1 2 3 console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5 [...document.querySelectorAll('div')] // [<div>, <div>, <div>] {...{a: 1}, ...{a: 2, b: 3}} // {a: 2, b: 3} [...[1], ...[2, 3]] // [1, 2, 3] const arr = [1] arr.push(...[2, 3]) // arr:[1, 2, 3
默认参数:
function log(x, y = 'World') { console.log(x, y) } log('Hello') // Hello World log('Hello', undefined) // Hello World log('Hello', 'China') // Hello China log(undefined, 'China') // undefined China log(, 'China') // 报错 SyntaxError log('Hello', '') // Hello log('Hello', null) // Hello null
参数不传递或是传递undefined会让参数等于默认值,若是参数不是最后一个,不传递参数就会报错。
传递null不会让函数参数等于默认值。
// 获取函数全部的参数,rest 为数组 function func1(...rest){ /* ... */} // 获取函数第一个参数外其余的参数,rest 为数组 function func1(val, ...rest){ /* ... */}
模板字符串:
var str = `abc def gh`; console.log(str); let name = "小明"; function a() { return "ming"; } console.log(`个人名字叫作${name},年龄${17+2}岁,性别${'男'},游戏ID:${a()}`);
函数的默认参数:
function A(a,b=1){ console.log(a+b); } A(1); //2 A(2+3); //5 function A(a,b=1){ console.log(a+b); } A(1); //2 A(2+3); //5
箭头函数:
//省略写法 var people = name => 'hello' + name; var getFullName = (firstName, lastName) => { var fullName = firstName + lastName; return fullName; }
对象的扩展:
var foo = 'bar'; var baz = {foo}; //等同于 var baz = {foo: foo};
var o = { method() { return "Hello!"; } }; // 等同于 var o = { method: function() { return "Hello!"; } };
Promise对象
它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败。
var promise = new Promise((resolve, reject) => { var success = true; if (success) { resolve('成功'); } else { reject('失败'); } }).then( (data) => { console.log(data)}, (data) => { console.log(data)} )
set数据结构
size 数据的长度
add() 添加某个值,返回 Set 结构自己。
delete() 删除某个值,返回一个布尔值,表示删除是否成功。
has() 查找某条数据,返回一个布尔值。
clear() 清除全部成员,没有返回值。
Spread Operator 展开运算符(...)
将字符串转成数组
var str="abcd"; console.log([...str]) // ["a", "b", "c", "d"]
将集合转成数组
var set = new Set([1,2,3,4,5]) console.log([...set]) // [1, 2, 3, 4, 5]
数组的合并
var a1=[1,2,3]; var a2=[4,5,6]; console.log([...a1,...a2]); //[1, 2, 3, 4, 5, 6]
rest参数 …变量名称
function func(...args){ console.log(args); //[1, 2, 3, 4] } func(1, 2, 3, 4); function f(x, ...y) { console.log(x); console.log(y); } f('a', 'b', 'c'); //a 和 ["b","c"] f('a') //a 和 [] f() //undefined 和 []
经典
var val = "全局变量"; { let val = "局部变量"; console.log(val); // 局部变量 } console.log(val); // 全局变量 const val = "常量"; val = "123"; // Uncaught TypeError: Assignment to constant variable.
迭代器iterator、for...of和for...in
//for in 会继承 for (let i in iterable) { console.log(i); // 依次打印 0, 1, 2, "foo", "arrCustom", "objCustom" } for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // 依次打印 0, 1, 2, "foo" } } // for of for (let i of iterable) { console.log(i); // 依次打印 3, 5, 9 }
forEach,for in,for of三者区别:
forEach来遍历数组,for in 遍历对象或json,for of数组对象均可以遍历,for in 循环出的是key,for of 循环出的是value。
const promise = new Promise((resolve, reject) => { console.log(1); resolve(); console.log(2); }) promise.then(() => { console.log(3); }) console.log(4);
1 2 4 3
Promise.then() 内部的代码在 当次 事件循环的 结尾 马上执行
关于目前文章内容即涉及前端,PHP知识点,若是有兴趣便可关注,很荣幸,能被您发现,真是慧眼识英!也感谢您的关注,在将来的日子里,但愿可以一直默默的支持我,我也会努力写出更多优秀的做品。咱们一块儿成长,从零基础学编程,将 Web前端领域、数据结构与算法、网络原理等通俗易懂的呈现给小伙伴。分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯。
推荐阅读
一、你知道多少this,new,bind,call,apply?那我告诉你
二、为何学习JavaScript设计模式,由于它是核心
三、一篇文章把你带入到JavaScript中的闭包与高级函数
意见反馈:
若本号内容有作得不到位的地方(好比:涉及版权或其余问题),请及时联系咱们进行整改便可,会在第一时间进行处理。
感谢阅读,原创不易,喜欢就点个赞吧,这是我写做最大的动力。
这是一个有质量,有态度的博客