资讯专栏INFORMATION COLUMN

【前端工程师手册】this拾遗之关于箭头函数的种种

oogh / 2534人阅读

摘要:之前总结了的一些常见绑定情况前端工程师手册之的笔记,但是还有一些没有说到,今天继续学习一下。参考资料箭头函数你不知道的上卷

之前总结了this的一些常见绑定情况(【前端工程师手册】JavaScript之this的笔记),但是还有一些没有说到,今天继续学习一下。

es6箭头函数

先说结论:箭头函数没有自己的this,它是根据外层(函数或者全局,后面会说到箭头函数作为某个对象的方法时的情况)作用域来决定this,箭头函数可以像 bind(..) 一样确保函数的 this 被绑定到指定对象,也就是说它在运行中不会丢失this,它的this是在声明箭头函数时就决定了。

一个例子
var name = "out"
function  test(){
    this.name = "in";
    setTimeout(function(){
        console.log(this.name)
    },1000)
}
new test() // 1秒后打印"out"

上面这个是es5中常见的this问题,计时器1s后运行匿名函数,this已经丢失了,于是默认绑定到了window上。
之前的经典处理方法是:

var name = "out"
function  test(){
    this.name = "in";
    var self = this;
    setTimeout(function(){
        console.log(self.name)
    },1000)
}
new test() // 1秒后打印"in"

显式的使用self来保存住正确的this,防止this丢失。
其实这些都可以使用箭头函数来实现:

var name = "out"
function  test(){
    this.name = "in";
    setTimeout(() => {
        console.log(this.name)
    },1000)
}
new test() // 1秒后打印"in"

在上面的代码片段中,箭头函数内部的this在声明期间就绑定为外层函数的this,且在运行过程中不会被修改。

不能当做构造函数
var Agumon = () => {  this.name = "agumon" }

var agumon = new Agumon() // Uncaught TypeError: Agumon is not a constructor

使用箭头函数去当做构造函数来new对象会直接报错,不过这个也好理解,因为箭头函数并没有自己的this,new操作中有用到this的步骤它搞不定。

call或apply调用无效
function foo() {
// 返回一个箭头函数
    return (a) => {
        console.log( this.a ); 
    };    
}
var obj1 = {
    a:2
};
var obj2 = { a:3};
var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 不是3 

上面的代码片段显式的使用call来想把foodethis绑定到obj1,然而并不奏效,因为箭头函数的this并不会在运行时再被改变。

没有prototype
var Foo = () => {};
console.log(Foo.prototype); // undefined

箭头函数是没有原型的

不适用于作为对象的方法
var obj = {
    i: 10,
    b: () => console.log(this.i, this),
    c: function() {
        console.log( this.i, this)
    }
}
obj.b(); 
// undefined
obj.c(); 
// 10, Object {...}

刚刚说了根据外层作用域来决定this,上面代码片段中的对象obj还不足以生成作用域,再往上就是全局作用域了,所以this被绑定为window。
参考资料:
MDN-箭头函数
《你不知道的JavaScript-上卷》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107813.html

相关文章

  • 前端程师手册】JavaScript作用域拾遗

    摘要:昨天总结了一些作用域的知识前端工程师手册之作用域,但是发表完发现忘记了一些东西,今天拾个遗。循环完毕之后,,且此时生成了个匿名函数,由于这个匿名函数处在同一个词法作用域中,所以他们引用同一个,所以当他们执行时,自然而然就会打出。 昨天总结了一些作用域的知识【前端工程师手册】JavaScript之作用域,但是发表完发现忘记了一些东西,今天拾个遗。昨天说到了JavaScript中没有块级作...

    flyer_dev 评论0 收藏0
  • 前端技能拾遗

    摘要:本文主要是对自己前端知识遗漏点的总结和归纳,希望对大家有用,会持续更新的解释语言和编译型语言解释型语言与编译型语言的区别翻译时间的不同。命令会有变量声明提前的效果。硬绑定参考不同是返回对应函数,便于稍后调用则是立即调用。 本文主要是对自己前端知识遗漏点的总结和归纳,希望对大家有用,会持续更新的~ 解释语言和编译型语言 解释型语言与编译型语言的区别翻译时间的不同。编译型语言在程序执行之前...

    lyning 评论0 收藏0
  • 前端技能拾遗

    摘要:本文主要是对自己前端知识遗漏点的总结和归纳,希望对大家有用,会持续更新的解释语言和编译型语言解释型语言与编译型语言的区别翻译时间的不同。命令会有变量声明提前的效果。硬绑定参考不同是返回对应函数,便于稍后调用则是立即调用。 本文主要是对自己前端知识遗漏点的总结和归纳,希望对大家有用,会持续更新的~ 解释语言和编译型语言 解释型语言与编译型语言的区别翻译时间的不同。编译型语言在程序执行之前...

    Vultr 评论0 收藏0
  • 前端技能拾遗

    摘要:本文主要是对自己前端知识遗漏点的总结和归纳,希望对大家有用,会持续更新的解释语言和编译型语言解释型语言与编译型语言的区别翻译时间的不同。命令会有变量声明提前的效果。硬绑定参考不同是返回对应函数,便于稍后调用则是立即调用。 本文主要是对自己前端知识遗漏点的总结和归纳,希望对大家有用,会持续更新的~ 解释语言和编译型语言 解释型语言与编译型语言的区别翻译时间的不同。编译型语言在程序执行之前...

    kevin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<