js 箭头函数和平凡函数的区别和this指向看这篇就够了

源代码 2024-9-6 15:08:24 80 0 来自 中国
this指向标题是个老标题了,网上的教程很多都是相互copy的,让萌新一脸蒙,这里简单总结下,包管一次性搞懂。
起首,这里有个标题是js严酷模式非严酷模式,严酷模式和非严酷模式下this指向稍微有点区别,主要就是全局作用域中平凡函数中的this指向标题,严酷模式下是指向undefined的,非严酷模式下是指向window。


如今一样平常用的都是严酷模式,好比vue中就是如许。


本文案例都是在严酷模式下。

话入正题:箭头函数和平凡函数有什么区别?

箭头函数没有arguments参数、无法作为构造函数,不能被new、this取决于上下文,自己没有this、使用call,apply等无法改变this指向。
而上面箭头函数不能做的平凡函数都可以,此中平凡函数的this指向调用方。
平凡函数this指向?

答:平凡函数的this指向调用方。
eg1:


起首这两种写法都是一样的,这里 a.say是对象a在调用,由于平凡函数的this指向调用方,因此这里的this指向a。
eg2:我们再来验证下:

4.png
这里我们将a.say的方法引用赋值给了b,然后用window.b调用,因此这里的this.name中this指向window
箭头函数this指向?

答:箭头函数自己没有this,this取决于界说时的上下文。也就是说箭头函数中的this指向的是界说时的this,而不是实行时间的this。
eg1:


这里say方法是箭头函数,在界说时a对象内是没有this的,当前this指向window.。window.b()固然末了打印的是全局name,但是现实上是和调用方无关的,this是在界说的时间就确定了。
eg2:


这里箭头函数界说在函数内部,若当做平凡函数直接调用,this为undefined,若当做构造函数实例化则this指向构造函数所创建的对象实例。
有的同砚就想,哎呀?不是一开始就确定了this吗,怎么值还不一样诶?留意,这里当做构造函数使用相当于把它当做了,性子都不一样,this不一样完满是可以明确的。
另有一点要留意,这里是用的new 一个实例的方式调用的,在严酷模式下构造函数不加new直接调用,由于this是undefined,this.name = xxxx 会报错,如下:


eg3:

8.png
这个例子出自这篇文章,具有误导性,但是明确了上面eg2这个例子你就明确了。这里person当做构造函数在使用,函数内getval是界说在构造函数内部的箭头函数,由于对象o在界说时是没有this的,因此getval内的this是构造函数的this,也就是指向构造函数所创建的对象实例。但是,person并没有返回这个this,该构造函数返回的是另一个对象o,但无论是返回的什么,getval的this在界说时就确定了,那就是构造函数内的this。
下面是测试使用的代码,方便各人测试:
    // ----------------- 分割线 ---------------------    "use strict"    window.name = '这是全局界说的name'    var a = {        name: '11',        say(){            console.log(this.name)        }    }    a.say()    // ----------------- 分割线 ---------------------    "use strict"    window.name = '这是全局界说的name'    var a = {        name: '11',        say(){            console.log(this.name)        }    }    var b = a.say    window.b()    // ----------------- 分割线 ---------------------    "use strict"    window.name = '这是全局界说的name'    var a = {        name: '11',        say: () => {            console.log(this.name)        }    }    a.say()    var b = a.say    window.b()    // ----------------- 分割线 ---------------------    "use strict"    var fn = function () {        this.name = '这是函数内界说的name'        console.log(this)        var a = {            name: '11',            say: () => {                console.log(this)            }        }        a.say()    }    var b = new fn()    //    fn()    // ----------------- 分割线 ---------------------    "use strict"    function person(fg) {        this.name = '这是person内部'        let o = new Object()        o.flag = fg        o.getval = () => {            console.log(this)        }        return o    }    let pp = new person('251')    pp.getval()进阶:留意this指向改变标题

    "use strict"    var obj = {        func() {            console.log('-----', this)            function fn() {                console.log('func', this)            }            fn()        },        func1() {            console.log('-----', this)            setTimeout(function () {                console.log('func1', this);            })        },        func2() {            console.log('-----', this)            setTimeout(() => {                console.log('func2', this);            })        }    }    obj.func();    obj.func1();    obj.func2();
9.png
若对你有资助,请点个赞吧,谢谢支持!
本文地址:https://www.jianshu.com/p/cdf9e4f6312b,转载请注明出处,谢谢。
参考:
https://blog.csdn.net/m0_61843874/article/details/123247934
https://blog.csdn.net/tanzhou123/article/details/105919159?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165577960616782388095394%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165577960616782388095394&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-105919159-null-null.142v19control,157v15new_3&utm_term=%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E7%9A%84this%E6%8C%87%E5%90%91+%E9%98%AE%E4%B8%80%E5%B3%B0&spm=1018.2226.3001.4187
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-24 10:10, Processed in 0.178507 second(s), 36 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表