如何在浏览器中使用es6的语法呢?
方法一:引入文件相关js文件
<script src="traceur.js"></script>
<script src="bootstrap.js"></script> //引导程序 --- 跟css的bootstrap无关
<script type="module">
//code 这里写你的代码
</script>
方法二:
在线编译 测试 --- https://babeljs.io/repl/
注意:玩ES6的时候,用严格模式('use strict'),如果不出问题的情况下,不用加编译,出问题再加。
1. 变量定义(let)和常量定义(const)
let 定义变量 (浏览器已经支持),有块级别作用域(只在本块有用,不会影响其他的)
{
let a = 12;
}
alert(a); //不能用
应用:可解决i值的问题。
let aBtn = document.getElementsByTagName('input');
for(let i = 0;i<aBtn.length;i++){
aBtn[i].onclick = function(){
alert(i); //点谁就弹几
};
}
注意:let不能重复定义同一变量。
错误示例:
'use strict'
let a = 12;
let a = 5;
alert(a); //会报错
定义常量(const)
const a = 'Tab';
alert(a);
1.不能重复定义
2.常量不能修改
2.字符串模板引擎(字符串拼接)
Es6的这种新的“字符串拼接”方法比较简单,没有繁琐的加号和引号,只需要在所需要的字符串“边界”加上``即可。(键盘 tab上面那个键 ${变量} 键盘 tab上面那个键)
var name = 'Datura';
var age = 18;
var sex = '其它';
var hobby = '敲代码';
var str1 = `我是${name},今年${age}岁,性别${sex}的了,爱好${hobby}`; //注意此处有两个“ `` ”
var str2 = '我是'+name+',今年'+age+'岁,性别'+sex+',爱好'+hobby+''; //这个是原来的写法
alert(st1r);
3. 解构赋值
就根据“对应”赋值,请看以下几个例子:
'use strict';
let a = 12;
let b = 5;
let c = 8;
//相当于
let [a,b,c] = [12,5,8];
console.log(a,b,c); //12 5 8
json格式的赋值
let {a,b,c} = {a:12,b:5,c:8};
console.log(a,b,c); //12 5 8
//数组里面嵌套数组
let [a,[b,c],d] = [12,[1,3],8];
console.log(a,b,c,d); // 12 1 3 8
与顺序无关,与结构有关(左右结构一致):
let {a,b,c} = {b:5,a:12,c:8};
console.log(a,b,c); //12 5 8
应用,我们现在利用jsonp获取了一组数据
let json = {
q:"aaa",
p:false,
s:["aaa云主机","爱奇艺vip免费试用","啊aaaaaaaa视频","aaaa","爱奇艺","aaa电池","工商银行","aaai","aaa短信轰炸机"]
};
let {s,q} = json;
console.log(s,q); //s为那组数组的数据,q为字符串aaa
解构赋值的默认值问题
let {time=1000,id=0} = {};
console.log(time,id); // 1000 0
4.神奇的“三个点”
我之前的文章曾提到过数组或者对象的深浅拷贝问题,今天我们就利用es6的三个点来处理下。
var arr = [12,5,8];
arr2 =arr;
arr2.pop();
alert(arr); // 12 5
上面的代码就是arr2与arr公用一段内存地址,所以导致srr2数据改变的时候arr也必然会变的。这就是浅拷贝。那么我们下面就简单的说几种深度复制数组方式。
方式一:利用for循环把原数组的每一项都遍历,然后扔到新的数组中。
var arr = [12,5,8];
var arr2 =[];
for(var i = 0;i<arr.length;i++){
arr2.push(arr[i]);
}
arr2.pop();
alert(arr); // 12 5 8
方式二:利用Array.from(原数组);
var arr = [12,5,8];
var arr2 = Array.from(arr);
arr2.pop();
console.log(arr2); // 12 5
alert(arr); // 12 5 8
方式三:三个点
var arr = [12,5,8];
var arr2 = [...arr]
arr2.pop();
console.log(arr2);//12 5
alert(arr); //12 5 8
说了这么多,我们现在就说下“三个点”的应用把,我们知道函数的参数是一个集合(arguments)并不是一个真正的数组。那么我们怎么才能在这个arguments中加一项呢??
function show(){
//因为类数组对象,并不具备数组的那些方法。所以此会报错
arguments.push(8);
console.log(arguments);
}
show(12,5);
function show(...arr){
arr.push(8);
console.log(arr);
}
show(12,5); //12 5 8
当然还有很多的对象深拷贝方式请参照(http://www.jianshu.com/p/4e613af9509c),这里就不一一论述了。
1. Map对象
ES6提供了新的数据结构Map,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。{"b" => "banana"}并且每一项都包含了key和value
我们来新建一个Map对象,并为其赋值:
let map = new Map();
map.set('a','apple');
map.set('b','banana');
console.log(map); // Map {"a" => "apple", "b" => "banana"}
结果如图:
获取Map对象里面的值(map.get()):
let map = new Map();
map.set('a','apple');
map.set('b','banana');
console.log(map.get('b')); //banana
删除Map对象里面的值(map.delete();):
let map = new Map();
map.set('a','apple');
map.set('b','banana');
map.delete('a');
console.log(map); // {"b" => "banana"}
获取Map对象的“长度”:
let map = new Map();
map.set('a','apple');
map.set('b','banana');
console.log(map.size); //2
console.log(map.length); //undefined
map.entries()
let map = new Map();
map.set('a','apple');
map.set('b','banana');
console.log(map.entries()); // MapIterator {["a", "apple"], ["b", "banana"]}
遍历Map对象(for...of... )
let map = new Map();
map.set('a','apple');
map.set('b','banana');
for(let name of map){
console.log(name); //["a", "apple"] ["b", "banana"]
}
//循环出来的是以数组套键值对的方式
如果我们只要Map中的“值”怎么办?别急
let map = new Map();
map.set('a','apple');
map.set('b','banana');
for(let val of map.values()){
console.log(val); //apple banana
}
如果我们只要Map中的“键(key)”怎么办?别急
let map = new Map();
map.set('a','apple');
map.set('b','banana');
for(let key of map.keys()){
console.log(key); // a b
}
如果我们只要Map中的“键 --- 值”怎么办?也别急
let map = new Map();
map.set('a','apple');
map.set('b','banana');
for(let [key,value] of map.entries()){
console.log(key,value); //a apple b banana
}
2.for循环那些事
a) for ... in ...循环
//循环数组
let arr = [12,5,8];
for(let i = 0;i<arr.length;i++){
console.log(i); //0 1 2
console.log(arr[i]); //12 5 8
}
let arr = [12,5,8];
for(let i in arr){
console.log(i); //0 1 2
console.log(arr[i]); //12 5 8
}
//循环json数据
let json = {a:12,b:5,c:8};
for(let name in json){
console.log(name); //a b c
console.log(json[name]); //12 5 8
}
b) for ... of ...循环
//循环数组
let arr = [12,5,8];
for(let name of arr){
console.log(name); // 12 5 8
}
//循环json数据
let json = {a:'apple',b:'banana'};
for(let name of json){
console.log(name);
}
//报错,因为不能用for ...of...来循环json数据
c) 删除json的某一条数据
let json = {a:12,b:5};
delete json.a;
console.log(json); // b:5
3. 箭头函数
ES6标准新增了一种新的函数:Arrow Function(箭头函数)。
为什么叫Arrow Function?因为它的定义用的就是一个箭头:
x => x * x
我们先回顾下ES5函数定义与调用:
var show = function(){
alert(12);
};
show(); // 12
const show = () =>{
alert(12);
};
show(); // 12
//个人理解:这里将function关键字去掉然后在“()”后面加一个“=>”
接下来我们举几个例子,来进一步了解下箭头函数:
a) 函数有返回值
//ES5函数写法
var sum = function(a,b){
return a+b;
}
alert(sum(12,5));
//ES6函数写法
let sum = (a,b) => {
return a+b;
}
alert(sum(12,5));
//进化一下 --- 省略花括号
let sum = (a,b) => a+b;
alert(sum(12,5));
b) 参数是1个
var show = function(a){ return 'welcome'}
//相当于 省略括号
var show = a => 'welcome'
c) 参数是0个
var show = function(){ return 'welcome'}
//相当于 省略括号
var show = () => 'welcome'
注意:箭头函数下 ,arguments 不能使用了
var show = (a,b) => console.log(this.arguments); // 报错
箭头函数简单应用:
数组排序
var arr = [12,55,8];
//es5写法
arr.sort(function(n1,n2){
return n1 - n2;
});
//es6写法
arr.sort((n1,n2) => n1-n2);
alert(arr);
1. 面向对象
a) 单例模式(单体模式)
let name = 'Datura';
let age = 18;
let person = {
name,
age,
sex:'Man',
showName:function(){return this.name},
showAge:function(){return this.age}
};
alert(person.showAge()); //18
alert(person.sex); //Man
b) 工厂模式
es5的面向对象工厂模式:
首先让我们一起来回一下es5面向对象的写法:
i) 首先定义一个构造函数(此处是 Person);
ii) 定义Person的“属性”,用this.xxx = xxx;
iii) 把方法挂在原型上,Person.prototype.xxx = function(){ xxx };
iiii) 调用
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.showName = function(){
return this.name;
};
Person.prototype.showAge = function(){
return this.age;
};
var p1 = new Person('alice',18);
alert(p1.showAge()); //18
es5继承:
//定义一个Person构造函数
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.showName = function(){
return this.name;
};
Person.prototype.showAge = function(){
return this.age;
};
//Worker构造函数
//继承属性
function Worker(name,age,job){
//改变this指向,继承Person的属性
Person.apply(this,arguments);
//定义worker新的属性
this.job = job;
}
//继承方法
Worker.prototype = new Person();
//给worker指定“亲爹”
Worker.prototype.construcotr = Worker;
//定义worker新的方法
Person.prototype.showJob = function(){
return this.job;
};
//调用
var p2 = new Worker('Datura',20,'boss');
alert(p2.showName()); //Datura
alert(p2.showJob()); //boss
es6的面向对象工厂模式:
i) 首先定义一个构造函数(此处是 Person),注意用class关键字而不是function;
ii) 定义Person的“属性”,写在constructor(){this.xxx = xxx };
iii) 定义方法,xxx () { xxx };
iiii) 调用
iiiii) 注意constructor和方法之间没有“;”,可以给属性初始值或默认值
class Person{
constructor(name,age=25){ //可以给属性初始值或默认值,正常es的function函数也可以给默认值
this.name = name;
this.age = age;
}
showName(){
return this.name;
}
showAge(){
return this.age;
}
}
var p1 = new Person('alice',18);
alert(p1.showAge()); // 18
es6继承:
//父类构造函数Person
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
return this.name;
}
showAge(){
return this.age;
}
}
//子类继承父类
class Worker extends Person{
constructor(name,age,job='搬砖的'){ //继承父类属性,并新加属性给默认值
super(name,age);
//这里必须传参,也就是需要把原来构造函数的参数传入。
//子类必须在constructor方法中调用super方法,否则新建实例时会报错。
//这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
this.job = job;
}
//给子类定义新方法showJob
showJob(){
return this.job;
}
}
//调用
var w1 = new Worker('rose',17);
alert(w1.showJob());
alert(w1.showName());
2. 模块化
注意:目前还没有浏览器支持模块化(需要引入traceur.js和bootstrap.js)
第三方:seajs require.js 模块化工具
那么我们来学习下,es6自带的模块化
a).导出,将变量a“暴露”出去
const a =12;
export default a;
b).导入1.js文件“暴露”的东西,并用modA 接收
import modA from './1.js'; (./代表同级目录下)
c).同一个模块导出多个值 export default {a:12,b:5};
d).不同模块间的引入
import modA from './mod1.js';
import modB from './mod2.js';
let sum = modA+modB;
export default sum;
实例写个小例子:
//mod1.js文件的内容
const a = 12;
export default a;
//mod2.js文件的内容
const b = 5;
export default c;
//主入口(模块)的内容
<script src="traceur.js"></script>
<script src="bootstrap.js"></script>
<script type="module">
import modA from './mod1.js';
import modB from './mod2.js';
alert(modA+modB); //17
</script>
一个子模块“暴露”一个json数据
//mod3.js文件的内容
export default {a:12,b:5};
//主入口(模块)的内容
import modA from './mod3.js';
console.log(modA.a+modA.b); // 17