es6作为新规范,为我们带来了许多便利的新特性,而这些特性数量繁多,想要完全掌握估计得花不少时间。为此,我总结了es6中一些常用或常见的特性和功能,大家不妨先看一看。
const和let
以往,我们在声明变量时使用的都是var关键字,而在es6中,我们不仅能使用新的let关键字声明变量,还能使用const关键字声明常量。
常,有经久不变的意思,而常量则相对于变量,是不会被改变的量。如:const foo=1,正常情况下这个foo的值永远都是1,只要声明了,就无法改变。而通过let声明的是变量,是能够被改变的。
可能很多人会问,既然用var就能创建变量了,为什么还要用let呢?
答案很简单,因为他们声明的变量的作用域不一样。
通过var关键字创建的变量作用域为函数作用域,通俗来讲就是以函数来区分有效范围;而通过let关键字创建的变量作用域为块级作用域,通俗来讲就是以{}来区分有效范围。
比如说,在for、switch或者if里,我们声明的变量不想被其他地方访问到,这时候let关键字就能很好地为我们解决问题了。
模板字符串
在渲染数据时我们常常用到模板,但传统的字符串拼接非常复杂且容易出错,维护性较差。不过,也因此衍生出了出各种各样的模板引擎,比如说我常用的baiduTemplate。
但是,模板引擎毕竟是第三方插件,作为有追求的开发者,第三方的东西当然是能不用就不用了。这时候,就该是我们的es6反引号登场了。
在es6中,我们能通过反引号来拼接字符串(反引号一般在键盘esc键的下方)、${}嵌入变量。
如:
let txt='hello es6';
let html=`
<div class="wrap">
<div class="inner">${txt}</div>
</div>
`;
document.body.innerHTML=html;
箭头函数
箭头函数是es6中新增的一种定义函数的方法,与function关键字的区别除了写法以外,最大的不同在于this的指向。
//function关键字定义函数
function bar( arg ){ content };
var bar=function( arg ){ content };
//箭头函数
let bar=( arg )=>{ content };
//this指向对比
let obj={
foo:function(){
console.log(this);
},
bar:()=>{
console.log(this);
}
};
obj.foo(); //obj
obj.bar(); //window
由于function关键字定义的函数是在执行时绑定this指向的,所以this指向调用她的对象obj;而箭头定义的函数是在定义时绑定this指向的,箭头函数定义时的上下文是window.obj.bar,自然this指向的就是window了。
我们可以利用这个特性使一些操作变得方便。
如:
let obj={
num:6,
baz:functiton(){
(()=>{
console.log(this.num);
})();
}
};
obj.baz(); //6
对象的省略写法
//以往的写法
let a=0;
let obj={
a:a
};
//对象中key和值变量是一样的话,可以进行省略
let a=0;
let obj={
a
};
//函数也能省略
let obj={
bar(){
console.log(this);
}
};
obj.bar();
Object新方法
Object.keys()方法能够列举对象的键,参数为对象,返回该对象的键所组成的数组。
//Object.keys()
let obj={
a:0,
b:1,
c:2
};
let arr=Object.keys(obj);
console.log(arr); //['a','b','c']
Object.assign()方法能够合并两个对象,用法与数组的concat方法差不多:第一个参数为主要合并对象,第二个参数为被合并对象。
//Object.assign()
let obj={
a:0,
b:1,
c:2
};
let obj2={
b:6,
d:3
};
Object.assign(obj,obj2);
let arr=Object.keys(obj); //['a','b','c','d']
console.log(obj.b); //6
从上面的例子中可以看到,如果合并的两个对象拥有相同的键,主对象的键的值会被替换掉。
class(类)
在js中,虽然可以通过构造函数创建类,但这种构造方式不直观,没有语义,对初学者来说可能不太好理解。为此,es6中新增了class构建类的方法。
class Foo{
constructor(a,b){
this.a=a;
this.b=b;
}
bar(){
console.log(this.a+this.b);
}
};
let foo=new Foo(1,2);
foo.bar(); //3
使用class方法构造类,语义清晰,class关键字直接跟上类名、花括号,而构造则由constructor方法来实现,其他类方法与constructor平级创建即可。实例化的话跟以往一样,还是使用new关键字创建。
创建过程非常直观,但有一点需要注意,class构造的类的花括号里具有固定写法:方法创建必须使用简写:方法间不需要也不能用任何分隔符。
另外,类里面的所有方法都绑定到prototype属性上,我们可以通过这个属性访问这些方法。
继承方面,class创建的类继承起来特别简单,只要使用extends关键字就可以了。
class Foo{
constructor(a,b){
this.a=a;
this.b=b;
}
bar(){
console.log(this.a+this.b);
}
};
class Baz extends Foo{
constructor(a,b,c){
super(a,b);
this.c=c;
}
foobar(){
console.log(this.a+this.b+this.c);
}
};
let baz=new Baz(1,2,3);
baz.bar(); //3
baz.foobar(); //6
class 类名 extends 父类名的方式就能实现继承,在constructor中使用super方法把参数传给父类。
回想起以往使用call传参继承,之后还要另外使用prototype继承方法,这种继承办法真的方便太多了。
Object.defineProperty()
这其实也算是Object对象新增的方法,但由于内容比较多,所以单独拿出来讲。
Object.defineProperty()的主要作用是:为目标对象添加或修改属性。不过,这种方法除了能够处理属性的值以外,还能设置各种特性。
首先我们来看看她是怎么写的:
Object.defineProperty(目标对象,需要设置的属性键,{
value:值,
writable:布尔值,
enumerable:布尔值,
configurable:布尔值,
get:function(){},
set:function(){}
});
从上述例子可以基本了解到defineProperty方法的写法和参数。
Object.defineProperty方法的参数有三个: 1、目标对象;2、为对象设置的属性名(key);3、目标属性特征的设置项(descriptor)。
descriptor对象里一共有六个属性可以设置:
value:设置属性的值;
writable:设置属性是否能被修改,true为能够被修改、false为不能被修改;
enumerable:设置目标属性是否能被枚举,true为能被枚举、false为不能被枚举;
configurable:设置目标属性是否能被delete关键字删除以及目标属性的特性能否被再次设置;
get:获取目标属性时触发该函数;
set:设置目标属性时触发该函数。
注:当使用get和set时,不能使用value和writable这两个属性。
下面贴上几个例子:
//为对象添加属性和值
let obj={};
Object.defineProperty(obj,'a',{
value:1
});
console.log(obj.a); //1
//修改目标属性的值
let obj={
a:1
};
Object defineProperty(obj,'a',{
value:2
});
console.log(obj.a); //2
//设置属性不能被修改
let obj={};
Object.defineProperty(obj,'a',{
value:1,
writable:false
});
obj.a=2;
console.log(obj.a); //1
//设置属性能被修改
Object.defineProperty(obj,'a',{
value:1,
writable:true
});
obj.a=2;
console.log(obj.a); //2
//设置目标属性为不可被枚举
let obj={};
Object.defineProperty(obj,'a',{
value:1,
enumerable:false
});
console.log(Object.keys(obj)); //[]
//设置目标属性能够被枚举
let obj={};
Object.defineProperty(obj,'a',{
value:1,
enumerable:true
});
console.log(Object.keys(obj)); //['a']
//设置为不能再设置特性
let obj={};
Object.defineProperty(obj,'a',{
value:1,
configurable:false
});
Object.defineProperty(obj,'a',{
value:2,
});
console.log(obj.a); //报错
//设置为能再次设置特性
let obj={};
Object.defineProperty(obj,'a',{
value:1,
configurable:true
});
Object.defineProperty(obj,'a',{
value:2,
});
console.log(obj.a); //2
//set和get的一种应用
function getEl(id){
return document.getElementById(id);
};
const oBox=getEl('box'),oBox2=getEl('box2'),oBtn=getEl('btn');
let obj={};
Object.defineProperty(obj,'a',{
get:function(){
return oBox.textContent; //4.get函数被触发,返回oBox的文本内容;另外值得注意的是,由于此时set函数里并没有设置a的值,所以无法返回没有的东西(无法return a)
},
set:function(val){
oBox.textContent=val; //2.set函数被触发,改变oBox的文本内容
}
});
oBtn.addEventListener('click',function(e){
obj.a=1; //1.点击按钮设置obj的a属性,触发set函数
oBox2.textContent=obj.a; //3.点击按钮获取obj的a属性,触发get函数,get函数返回值,改变oBox2的文本内容
},false);
本文中的几个新特性都是个人觉得比较常见或常用的,感兴趣或者有需要的不妨再深入研究一下。
最后提一下,由于现在浏览器对es6的支持并不理想,写完后记得用babel转一下码噢。