JS函数(普通函数,箭头函数)中this的指向问题详解

 更新时间:2022年09月04日 15:42:56   作者:hello_exec  
这篇文章主要给大家介绍了JS中普通函数和箭头函数的this指向,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

普通函数

具名普通函数、匿名普通函数,在不作为对象的属性值的情况下,其内部的 this 总是指向代码运行环境下的全局对象 ( 例如,浏览器中的 window )。

示例:

(function() {
    console.log(this); // window
    (function() {
        console.log(this); // window
        (function() {
            console.log(this); // window
        })()
    })()
})()  

普通函数,均可以通过其 bind、call、apply 方法 来改变其内部 this 的指向。

示例:

(function() {
    const func = (function() { console.log(this) }).bind('hello')
    const obj = {
        func,
        func1: (function() { console.log(this) }).bind('hello'),
        func2: (function F() { console.log(this) }).bind('hello')
    }
    func() // String {'hello'}
    obj.func() // String {'hello'}
    obj.func1() // String {'hello'}
    obj.func2() // String {'hello'}
})() 

当普通函数( 具名的、匿名的、外部定义的方法 ),作为对象的属性值被引用的时候,其内部的 this 指向该属性所直接归属的对象 。

示例:

(function() {
    const func = function() { console.log(this) }
    const obj = {
        func,
        func1: function F() { console.log(this) },
        func2() { console.log(this) },
        param: {
            func,
            func1: function F() { console.log(this) },
            func2() { console.log(this) }
        }
    }
    func() // window
    obj.func() // obj
    obj.func1() // obj
    obj.func2() // obj
    obj.param.func() // obj.param
    obj.param.func1() // obj.param
    obj.param.func2() // obj.param
})() 

箭头函数

箭头函数,不管是作为独立的方法 或是 作为对象的属性值,其内部的 this 均指向 该箭头函数被定义时所在的上下文中对应的 this。

示例:

(function() {
    /** 外层作用域 */
    const arrowfunc = () => console.log(this)
    
    console.log('-- 外层作用域 --');
    console.log(this); // String {'hello'}
    arrowfunc(); // String {'hello'}
    
    (function() {
        /** 内层作用域 */
        const arrowfunc1 = () => console.log(this)
        
        console.log('-- 内层作用域 --');
        console.log(this); // String {'world'}
        arrowfunc() // String {'hello'}
        arrowfunc1() // String {'world'}
 
        /** 函数作为对象属性值 */
        const obj = {
            arrowfunc,
            arrowfunc1,
            param: {
                arrowfunc,
                arrowfunc1,
                arrowfunc2: () => console.log(this)
            }
        }
        
        console.log('-- 函数作为对象属性值 --');
        obj.arrowfunc() // String {'hello'}
        obj.arrowfunc1() // String {'world'}
        obj.param.arrowfunc() // String {'hello'}
        obj.param.arrowfunc1() // String {'world'}
        obj.param.arrowfunc2() // String {'world'}
    }).bind('world')()
}).bind('hello')()

箭头函数 也有 bind、call、apply 方法,与普通函数一样可以通过这三个方法预设箭头函数的入参值。

试图通过这三个方法改变箭头函数内部 this 的指向,虽不会报错但却是无效的。

示例:

(function() {
    console.log(this); // String {'hello'}
    (() => {
        console.log(this); // String {'hello'}
        (() => {
            console.log(this) // String {'hello'}
        }).bind('bbb')()
    }).bind('aaa')();
    
    ((a, b, c) => {
        console.log(this) // String {'hello'}
        console.log(a) // a
        console.log(b) // b
        console.log(c) // c
    }).bind(null, 1, 2)(3)
}).bind('hello')()  

附:

* 箭头函数不能作为构造函数使用,强制使用 new 运算符作用在箭头函数上,将会报如下错误

new (() => {}) // Uncaught TypeError: (intermediate value) is not a constructor  

* 箭头函数内部没有定义 arguments 变量,箭头函数所在的作用域也不存在 arguments 的情况下,应用该变量会报错。

(function() {
    ((a) => {
        console.log(a) // 1
        console.log(arguments) // Arguments ['hello']
    })(1)
})('hello');
 
(() => {
    console.log(arguments) // Uncaught ReferenceError: arguments is not defined
})();

* 普通函数都有原型属性 prototype,箭头函数没有这个属性。

(function() {}).prototype // {constructor: ƒ}
(() => {}).prototype // undefined

到此这篇关于JS函数(普通函数,箭头函数)中this的指向问题详解的文章就介绍到这了,更多相关JS函数this的指向内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS 控制CSS样式表

    JS 控制CSS样式表

    JS控制CSS样式,首先得确定一点,CSS与HTML页面的链接方式,因为CSS有3种与HTML页面结合的方式,不同的方式也会产生不同的结果.
    2009-08-08
  • 微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)

    微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)

    这篇文章主要介绍了微信小程序授权登录解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Javascript 对象(object)合并操作实例分析

    Javascript 对象(object)合并操作实例分析

    这篇文章主要介绍了Javascript 对象(object)合并操作,结合实例形式分析了javascript基于jQuery的extend方法、对象属性、遍历赋值等操作实现对象合并相关操作技巧与使用注意事项,需要的朋友可以参考下
    2019-07-07
  • js中比较两个对象是否相同的方法示例

    js中比较两个对象是否相同的方法示例

    这篇文章主要介绍了js中比较两个对象是否相同的方法,结合实例形式详细分析了js对象遍历、判断等相关操作技巧,需要的朋友可以参考下
    2019-09-09
  • javascript判断非数字的简单例子

    javascript判断非数字的简单例子

    这篇文章介绍了javascript判断非数字的简单例子,有需要的朋友可以参考一下
    2013-07-07
  • JS+Canvas绘制动态时钟效果

    JS+Canvas绘制动态时钟效果

    这篇文章主要为大家详细介绍了JS+Canvas绘制动态时钟效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • javascript实现自动输出文本(打字特效)

    javascript实现自动输出文本(打字特效)

    文字如何实现打字的效果呢?在浏览网页的时候也经常能看到这种效果。本文给大家汇总介绍了几种打字效果的文字特效,文字一个一个地打印在页面上。
    2015-08-08
  • JS中for,for...in,for...of和forEach的区别和用法实例

    JS中for,for...in,for...of和forEach的区别和用法实例

    JS遍历数组(循环数组)的方式有多种,可以使用传统的for循环,也可以使用升级版的for in循环,还可以使用Array类型的forEach() 方法,这篇文章主要给大家介绍了关于JS中for、for...in、for...of和forEach的区别和用法的相关资料,需要的朋友可以参考下
    2021-11-11
  • 解决layui弹出层layer的area过大被遮挡的问题

    解决layui弹出层layer的area过大被遮挡的问题

    今天小编就为大家分享一篇解决layui弹出层layer的area过大被遮挡的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 原生js实现拼图效果

    原生js实现拼图效果

    这篇文章主要为大家详细介绍了原生js实现拼图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08

最新评论