es6(一)
来源:互联网 发布:淘宝有哪些部门 编辑:程序博客网 时间:2024/06/05 22:30
es6(一)
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
- es6在2017年可谓是大火,被越来越多的人频频提及,在React、ReactNative开发中广泛使用。javascript在es6的推出后,是越来越健全,真不能认为它是一个”玩具语言”啦。haha
较为深入的学习es6是非常有必要的,我总结了一些es6相关的语法特性及较为详细的使用说明,其中还有一些学习心得,希望可以给大家带来帮助。
什么是ES6 ?
es6的全名是ECMAscript 2015
es6有哪些新特性?
一、let
1. 没有变量提升
console.log(a); let a = 4; // a is not defined
2. 不能重复申明
let a = 4; let a = 5; console.log(a); // Identifier 'a' has already been declared
3. 临时失效区(暂时性死区)
var a = 5; function fn(){ console.log(a); let a = 4; } fn(); // a is not defined
4. 具有块级作用域(由花括号包裹的区域)
同样具有块级作用域的还有const。
来看一个例子
var a = 5; function foo(){ console.log(a); // undefined if(false){ var a = 6; } }
这显然不是我们想要的结果,因为
js在es6之前没有块级作用域
for(let i = 0; i < 3; i++){ console.log(i); } console.log(i); // 0 1 2 i is not defined
{ let a = 10; } console.log(a); // a is not defined
老生常谈的闭包问题 实质上就是为了解决没有块级作用域带来的问题
闭包
* 外部函数(作用域)中有内部函数(作用域)* 内部函数调用了外部函数的局部变量* 外部函数执行完后,因为内部函数还在使用该局部变量,所以该局部变量不被释放,保证内部函数正常使用* 闭包函数(立即执行函数)为 (function(){ // ...函数体 })();
var aLi = document.getElementsByTagName('li');// len = n for(var i = 0; i < aLi.length; i++){ aLi[i].onclick = function(){ console.log(i); } } // n......n
var aLi = document.getElementsByTagName('li');// len = n for(var i = 0; i < aLi.length; i++){ (function(i){ aLi[i].onclick = function(){ console.log(i); } })(i) } // 0、1、2....n
- for循环实质可以理解为 由n个”{}”构成的,在每个花括号中,let的作用域都是独立的,所以可以拿到每个i值。
- 但对于var来说实质是一个作用域,所以无法保留每个i的值。
二、const
在es6之前,如果我们想定义常量,通常由程序员自己约定
var NUM = 100;
将所有字母都大写的变量约定为常量,但本质还是变量
1.const定义只是地址不能修改
const NUM = 100; NUM = 200; // Assignment to constant variable.
由const定义的常量,无法修改其地址值。
在这里为啥要强调是地址值
因为 以下代码在非严格模式下是可以通过的
const OBJ = {a: 100}; OBJ.a = 200; console.log(OBJ.A); // 200
这时候会发现这很坑啊!!!
怎么办呢,如果我们想要定义一个常量对象呢
const OBJ = {a: 100}; Object.freeze(OBJ); OBJ.a = 200; console.log(OBJ.a); // 100
这样就可以了..
2.没有变量提升
3.块级作用域
let 和 const 声明的变量不挂在window上
三、class 类
在es6之前,我们要定义一个类,只能通过function来模拟
function Person(){ this.name = 'xxx'; } Person.prototype.say = function(){ } var person = new Person();
问:将属性放在原型中会怎么样?
如Person.prototype.name = 'xxx';
答:对于普通数据类型,没有问题,但对于引用类型,对一个对象的修改,会影响所有继承该类的对象
1.语法
class Person{ constructor(name){ this.name = name; } say() { console.log(this.name); } } var person = new Person(); person.say();
2.继承的实现
class Man extends Person{ constructor(name, food){ super(name, food); // 必须放在构造器的第一行,代表调用父类的构造方法 this.food = food; } eat(){ console.log(this.food); } } var man = new Man(); man.say();
3.static 静态方法/变量
class Person{ constructor(){ } static say(){ console.log(123); // 可以认为这是一个静态方法 } static name(){ return 'xxx'; // 可以认为这是一个静态变量 } } Person.say();
在es6中,规定Class 内部只有静态方法, 没有静态属性
以下写法都无效
class Person{ constructor(){ } name: 2 static name: 2 } console.log(Person.name) // undefined
四、Set 集合
Set是一个不能有重复元素的集合,重复添加无效
var s = new Set(); s.add(1); s.add(2); // s.delete(2) 删除 // s.clear() 清空 // s.size() 长度
1.遍历Set
var keys = s.keys(); // 返回一个迭代器 for(var k of keys){ console.log(k); } var values = s.values(); for(var v of values){ console.log(v); } var entries = s.entries(); // 将key和value 组合成一个数组返回 for(var e of entries){ console.log(e); }
如果我们想在es6之前使用给数组去重
2.Array数组去重问题
方法一:
var arr = [1,2,3,4,1,1,1]; function fn(arr){ var map = {}; var newArr = arr.filter(function(item, index){ if(!map[item]){ map[item] = true; return item; } }); return newArr; } fn(arr);
方法二:
var arr = [1,2,3,4,1,1,1]; function fn(arr){ var newArr = []; for(var i = 0; i < arr.length; i++){ if(newArr.indexOf(arr[i]) === -1){ newArr.push(arr[i]); } } return newArr; } fn(arr);
利用Array.from的方法三:
var arr = [1,2,3,4,1,1,1]; function fn(arr){ var s = new Set(arr); return Array.from(s); } fn(arr);
3.Array返回只出现一次的元素
var arr = [1,2,3,4,1,1,1]; function fn(arr){ var newArr = []; for(var i = 0; i < arr.length; i++){ if(arr.indexOf(arr[i]) === arr.lastIndexOf(arr[i])){ newArr.push(arr[i]); } } return newArr; } fn(arr);
五、Map(键值对)
var m = new Map(); m.set('a',1); m.set('b',2); m.get('a'); // 1 // m.delete('a')
对象的属性名 认为是字符串,但Map的键 可以是所有数据类型
forEach
可以遍历Array、Set、Map。
for of
被专门用来遍历迭代器。
六、arrow 箭头函数
终于来到了箭头函数的环节()=>{}
这是一种特别简洁、优雅的函数写法
他可以这么写
var fn = (item, index) => {console.log(item)}
也可以这么写
var fn = item => {console.log(item)}
还可以这么写
var fn = item => (item) fn(2) // 2
还可以更简洁
var fn = item => item fn(2) // 2
=>
后使用小括号()
表示将结果作为返回值,单行结果时还可以省略
当参数唯一时,还可以将前面的()
省略
但是他失去了一些东西…
var fn = () => { console.log(arguments); } fn(2) // arguments is not defined
解决方法如下:
var fn = (...arg) => { console.log(arg); } fn(2) // [2]
箭头函数不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
...
称为位扩展运算符,在下面会详细介绍
但箭头函数最厉害的地方还不在此
1.改变默认的this指向
箭头函数能够将函数外面的this指向同步到函数内部,比如说这样:
var aLi = document.getElementsByTagName('li');// len = n for(var i = 0; i < aLi.length; i++){ aLi[i].onclick = function(){ setTimeout(function(){ console.log(this.innerHTML); // 此时无法获取,因为this指向调用他的对象,而setTimeout为window下的方法,此时this指向window }) } }
将function改为箭头函数就能够正确运行
var obj = { a: 1, say: function(){ console.log(this.a); } } obj.say() // 1
上面乍一看这个挺正常的结果呀… 但是如果改成箭头函数
var obj = { a: 1, say: () => { console.log(this.a); } } obj.say() // undefined
所以箭头函数虽好,也要看清场合使用啊。
- ES6笔记(一)
- ES6深入浅出(一)
- ES6 基础教程(一)
- ES6手记(一)
- ES6学习(一)
- ES6入门(一)
- ES6入门(一)
- ES6(一)
- es6(一)
- 深入浅出ES6(一)
- 深入浅出ES6(一):ES6是什么
- 深入浅出ES6(一):ES6是什么
- 深入浅出ES6(一):ES6是什么
- 深入浅出ES6(一):ES6是什么
- ES6学习笔记(一)
- ES6入门笔记(一)
- es6学习系列---(一)
- webpack学习ES6(一)
- Java四种引用类型
- ROS 与非ROS 系统进行交互 --rosbridge
- Spring Cloud中Feign的继承特性
- restful中的token
- iOS 适配iOS11、iPhone X
- es6(一)
- MySQL的Grant命令
- 冒泡排序
- eclipse新建项目时显示no applicable items
- Linux手动添加SWAP分区
- Tomcat启动时卡在“INFO: Deploying web application directory ......”的解决方法
- 实验过程中一些不成体系的小Tips
- python爬取HTML网页
- MFC生成的exe文件在别人电脑无法正常运行