ES6 拾遗系列 一 :let 和 const , 解构赋值 , 展开运算符
ES6 拾遗系列 二 : 箭头函数 , 模板字符串
箭头函数
箭头函数难道单单只是书写方便吗
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的
this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
以上是 mdn 上对于箭头函数的说明,第一句话就说明了箭头函数的方便简洁。但是没有自己的this,arguments这句话要怎么理解呢。
以下是我自己的一点见解:
在普通函数中 this 的指向遵循如下原则:
- 通过对象调用函数,this 指向对象
- 直接调用函数,this指向全局对象
- 如果通过new调用函数,this指向新创建的对象
- 如果通过apply、call、bind调用函数,this指向指定的数据
- 如果是DOM事件函数,this指向事件源
接下来对比看下以上5个原则,使用箭头函数的表现
//1. 通过对象调用函数,this 指向对象
const obj = {
a:1,
b(){
console.log(this.a,this,arguments)
},
c:()=>{
console.log( this.a, this,arguments)
},
d(){
(()=>{
console.log(this.a,this,arguments)
})()
}
}
obj.b(100);// 1 obj 100
obj.c(100);// undefined window 报错
obj.d(100);// 1 obj 100
//2. 直接调用函数,this指向全局对象
function a(){
console.log(this,arguments)
}
const b = ()=>{
console.log(this,arguments)
}
function c(){
(()=>{
console.log(this,arguments)
})()
}
a(100);//window 100
b(100);//window 报错
c(100);//window 100
- 箭头函数不能作为构造函数,第三点就不用试了
//4. 如果通过apply、call、bind调用函数,this指向指定的数据
const obj = {
a:1,
b(){
console.log(this.a,this,arguments)
},
c:()=>{
console.log( this.a, this,arguments)
},
d(){
(()=>{
console.log(this.a,this,arguments)
})()
}
}
const obj1={
a:100
}
obj.b.call(obj1,1000); // 100 obj1 1000
obj.c.call(obj1,1000); // undefined window 报错
obj.d.call(obj1,1000); // 100 obj1 1000
<!-- 5. 如果是DOM事件函数,this指向事件源 -->
<button class="btn1">1</button>
<button class="btn2">2</button>
<button class="btn3">3</button>
<script>
document.querySelector('.btn1').addEventListener('click',function(){
console.log(this); //<button class="btn1">1</button>
})
document.querySelector('.btn2').addEventListener('click',()=>{
console.log(this); // window
})
</script>
综上例子,箭头函数中,不存在 arguments 且 this 的指向发生改变,如果使用了则使用的是函数外层的对应的this、arguments(专业的说箭头函数中的this 指向,箭头函数定义时所在的作用域的this)
怎么更加方便的使用箭头函数
箭头函数是一个函数表达式,其完整语法如下:
(参数1, 参数2, ...)=>{
//函数体
}
function(a,b){
let c = a+b;
return c
}
//等价于
(a,b)=>{
let c = a+b;
return c
}
如果是一个参数
参数 => {
//函数体
}
function(a){
a++;
return a;
}
//等价于
a=>{
a++;
return a;
}
箭头函数只有一条返回语句,可以省略大括号,和return关键字
参数 => 返回值
function(a){
return a++;
}
//等价于
a=>a++;
function(a,b){
return a+b;
}
//等价于
(a,b)=>a+b;
mdn 文档:箭头函数
模板字符串
模板字符串是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。
模板字符串取代了之前哪些繁琐的操作
在没有模板字符串时,字符串拼接是通过 “ + ” 来完成,例如
let name = '张三',age=12;
console.log('你的姓名是'+ name +',年龄是'+ age)
以上操作对于单行少量的字符串拼接来说还没有什么问题,但是对于多行字符串还需要在换行处加上 '\n'来处理,例如
let name = '张三',age=12,weight = 50;
console.log('你的姓名是'+ name + ',\n' +
'年龄是'+ age + ',\n' +
'体重是'+ weight);
以上代码如果不是复制粘贴,而是自己手敲一遍,你会发现其极为恶心,可读性也非常差,但是当开始使用模板字符串后,才发现世界是这么的美好,接下来使用模板字符串来改写上述代码
let name = '张三',age=12,weight = 50;
console.log(`你的姓名是${name},年龄是${age}`)
console.log(`
你的姓名是${name},
年龄是${age},
体重是${weight}
`)
模板字符串的骚操作
模板字符串使用反引号 (
) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符
占位符的内容不仅可以是变量,还可以是表达式,函数
function add(a,b){
return a+b;
}
let num1=1,num2=2;
console.log(`两个数${num1},${num2},这两数和为${add(num1,num2)},两数积为${num1*num2},num1是不是大于num2:${num1>num2?true:false}`)
除了以上功能,模板字符串还支持嵌套
const arr=[1,2,3,4];
console.log(`
这是一个数组${arr},
${arr.map((v,i)=>`第${i}项为${v}`)}
`)
mdn 文档:模板字符串