今天看啥  ›  专栏  ›  grossboy

js普通函数和箭头函数的this(全网最容易理解)

grossboy  · 掘金  ·  · 2019-06-24 07:43

文章预览

阅读 100

js普通函数和箭头函数的this(全网最容易理解)

最近在被箭头函数与普通函数的区别的时候,有一个非常重要的区别就是this指向问题。本身笔者比较笨的那种,所以下面我都理解,全网的程序员都应该没问题。说重点。。。

普通函数的this

首先我们来搞明白普通函数的this指向问题:

const obj = {
    bg:function(){
        console.log(this)    
    }
}
obj.bg() //obj
var dbl = obj.bg
dbj() //windows
复制代码

obj是一个对象,对象里面有过一个bg的属性,然后第一行obj.bg()执行,普通函数里面的this指向obj这个对象,第二行var dbl = obj.bg只做了赋值,并没有执行,也就说现在dbl只是一个普通函数,第三行执行了,此时普通函数里面的this指向window。

  • 1.普通函数最终指向调用它的对象,也就是说谁调用就指向谁。
  • 2.没有被对象调用的函数默认指向window
function test(){
    console.log(this)
}
test()     //windows
new test() //test对象
test.call({id:1}) // {id:1}对象 
复制代码

test是一个普通的构造函数,第一行执行此时普通函数里面的this指向window,符合上述观点,第二行new一个实例此时的this指向test的对象,这里有些小伙伴比较蒙了,不是说好的谁调用指向谁吗?怎么回事,那是我们不够了解new到底做了什么事。new关键字:1.创建了一个新的对象。2.将这个新的对象的__proto__指向了构造函数对象prototype对象。3.把构造函数的this指向这个对象并且执行,例如:test.call(newobj)。4.返回新的对象。 这个样一来我们就明白执行newtest()为什么指向test对象了,但是这不是我想表达的重点,我们再看第三行test.call({id:1}),call方法大家都很熟吧,就是用来改变this指针的函数,并且执行这个构造函数(相应的还有bind、apply函数)。那么这样一来同一个构造函数,不同的调用方式,this指向的对象也是不一样的。

  • 3.在函数没有调用的时候this的指向是无法确定的,也就是说普通函数的this是在执行的时候确定的。

箭头函数的this

再接着说剪头函数,其实箭头函数没有this,必须通过查找作用域链查找决定值。

const obj = {
    bg:() => {
        console.log(this)    
    }
}
obj.bg() //windows
复制代码

例子中的剪头函数bg的在obj调用函数的时候,this对obj对象没有绑定作用它会沿着作用域链往上找,再上层作用域是window所以输出结果是window;也就是说箭头函数没有this,它的this取决于作用域链上的this。 在这里笔者有一个误区,就是总以为bg的箭头函数上一层作用域是obj这个对象的块级作用域,其实bg是obj的一个属性,他们应该是同一级的作用域,我来换种写就可理解了const obj.bg = ()=> {}这样上层作用域就是window( 这里我还是要非常感谢笔者的同学X帮我从坑中解救出来,哈哈哈)

function test1(){
    return function(){
    console.log(this)
    }
}
var Test1 = new test1();  Test1() //windows

function test2(){
    return ()=>{
    console.log(this)
    }
}
var Test2 = new test2();  Test2() //Test2
复制代码

剪头函数的特殊本质就是函数中的this没有绑定作用,或者可以这样说:剪头函数中的this其实始终指向的是函数定义时的this的指向而非执行时的。

………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览