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的指向内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JS中不应该使用箭头函数的四种情况详解

    目录 箭头函数的一些缺点 1.不支持参数对象 2.无法通过apply.call.bind来改变this指针 什么时候不能使用箭头功能 1.请不要在构造函数中使用箭头函数 2.请不要在点击事件中操作this 3.请不要在对象的方法中使用箭头函数. 4.请不要在原型链中使用箭头函数 箭头函数给我们的工作带来了极大的方便,但是它们有什么缺点呢?我们应该一直使用箭头函数吗?我们应该在哪些场景中停止使用箭头函数? 现在,我们开始吧. 箭头函数的一些缺点 1.不支持参数对象 在箭头函数中,我们不能像在普通函

  • JavaScript箭头函数与普通函数的区别示例详解

    目录 箭头函数与普通函数的区别 箭头函数的理解 箭头函数里的this指向 总结 箭头函数与普通函数的区别 要讨论箭头函数和普通函数的区别,首先来看看两者的基本格式 普通函数和箭头共同点就是圆括号和大括号,圆括号里面一般放置参数,大括号一般放置函数主体,很明显箭头函数不需要写那么长,举个例子,有一个数组,使用map方法为数组的每个元素增加字符 let arr=['昨天','今天','明天'] let newarr=arr.map(function(item){ return item+='放假'

  • 一文带你玩转JavaScript的箭头函数

    目录 箭头函数 语法规则 简写规则 常见应用 map filter reduce 箭头函数中的this使用 concat this的查找规则 箭头函数 在ES6中新增了函数的简写方式----箭头函数,箭头函数的出现不仅简化了大量代码,也让代码看起来更加优雅,同时也解决了this指向问题,下面我们就来详细讲解如何玩转箭头函数. 语法规则 1.之前的方法 function foo1(){} var foo2 = function(name,age){ console.log("函数体代码"

  • 详解JavaScript什么情况下不建议使用箭头函数

    目录 this指向原理 问题的由来 内存的数据结构 函数 环境变量 箭头函数的缺点 不适用的场景 总结 箭头函数作为ES6新增的语法,在使用时不仅能使得代码更加简洁,而且在某些场景避免this指向问题.但是箭头函数不是万能的,也有自己的缺点以及不适用的场景,虽然可以解决this只想问题,但是也可能会带来this指向问题.具体场景具体分析,本文就深入探讨箭头函数. 箭头函数没有自己的this,其this取决于上下文中定义的this. this指向原理 问题的由来 学懂 JavaScript 语言,

  • JS字符串函数扩展代码

    复制代码 代码如下: /**************************************************** *CreateBy:joe zhou *CreateDate:2011-9-4 *Description:字符串辅助函数 ****************************************************/ //String.prototype = { // caption: function () { // }, // leftPad: fun

  • JavaScript箭头函数的五种使用方法及三点注意事项

    目录 使用 简略编写 结合解构赋值 结合扩展运算符 this指向的改变 绑定this 注意细节 关于构造 关于参数对象 关于yield命令 面试题 前言: 箭头函数是ES6新增的定义函数的方式,我们可以使用()=>{}来顶替以前的函数定义方式,下面从五个使用姿势与三点注意事项来刨析箭头函数. 使用 简略编写 当我们箭头函数函数只有一个参数的时候是可以将()省略,当代码块只有一行的时候可以将{}与return省略 const fn = num => num.sort(); console.log

  • js中什么时候不能使用箭头函数

    目录 箭头函数 箭头函数有什么缺点? 什么时候不能使用箭头函数? 1. 对象方法中,不适用箭头函数 为什么对象方法中,箭头函数的this指向不是这个对象? 2. 原型方法中,不适用箭头函数 3. 构造函数也不行! 4. 动态上下文中的回调函数 5. Vue 生命周期和 method 中也不能使用箭头函数 划重点 箭头函数 箭头函数是和我们工作密切相关的东西:可以说箭头函数的诞生,给我们的工作带来了极大的便利.但是箭头函数有什么缺点?什么时候不能使用箭头函数? 这你了解吗?我们觉得箭头函数很高级,

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

    目录 普通函数 箭头函数 普通函数 具名普通函数.匿名普通函数,在不作为对象的属性值的情况下,其内部的 this 总是指向代码运行环境下的全局对象 ( 例如,浏览器中的 window ). 示例: (function() { console.log(this); // window (function() { console.log(this); // window (function() { console.log(this); // window })() })() })() 普通函数,均可

  • JavaScript中的this指向问题详解

    前言 相信我,只要记住本文的 7️⃣ 步口诀,就能彻底掌握 JS 中的 this 指向. 先念口诀:箭头函数.new.bind.apply 和 call.欧比届点(obj.).直接调用.不在函数里. 按照口诀的顺序,只要满足前面某个场景,就可以确定 this 指向了. 接下来按照口诀顺序对它们进行详解,文中示例代码都运行在 Chrome 的 Console 控制台中. 文末有精心准备的练习题,用于检验学习成果,别忘了试试~ 1. 箭头函数 箭头函数排在第一个是因为它的 this 不会被改变,所以

  • JavaScript中的函数申明、函数表达式、箭头函数

    JavaScript中的函数可以通过几种方式创建,如下. // 函数声明 function getName() { return 'Michael' } // 函数表达式 const getName = function() { return 'Michael' } // 箭头函数(同样也是表达式) const getName = () => { return 'Michael' } 函数声明和表达式之间的差别是 JavaScript 解释器中存在一种变量声明被提升的机制,也就是说函数声明会被提

  • R语言dplyr包之高效数据处理函数(filter、group_by、mutate、summarise)详解

    R语言dplyr包的数据整理.分析函数用法文章连载NO.01 在日常数据处理过程中难免会遇到些难处理的,选取更适合的函数分割.筛选.合并等实在是大快人心! 利用dplyr包中的函数更高效的数据清洗.数据分析,及为后续数据建模创造环境:本篇涉及到的函数为filter.filter_all().filter_if().filter_at().mutate.group_by.select.summarise. 1.数据筛选函数: #可使用filter()函数筛选/查找特定条件的行或者样本 #filte

  • JavaScript进阶教程之函数的定义、调用及this指向问题详解

    目录 前言 一:函数的定义 1.1 命名函数 1.2 匿名函数 1.3 利用 new Function() 声明函数 1.4 重要结论 二:函数的调用 2.1 普通函数调用 2.2 立即执行函数调用 2.3 对象内方法调用 2.4 构造函数调用 2.5 事件函数的调用 2.6 定时器函数的调用 三:各类函数的内部this指向问题 总结 前言 这篇文章开始我们函数的进阶篇,和我们JavaScript基础学的函数有了很多拓展,这篇文章首先我们从函数的定义,调用,及其 this指向 来一个总结. 一:

  • Node.Js中实现端口重用原理详解

    本文介绍了Node.Js中实现端口重用原理详解,分享给大家,具体如下: 起源,从官方实例中看多进程共用端口 const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); for (let i =

  • JS中自定义事件与观察者模式详解

    目录 一.前言 二.观察者模式优缺点 三.代码实现 四.DOM自定义事件API 一.前言 观察者模式 也称发布-订阅模式 . 模型-视图模式 .当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知依赖它的对象.观察者模式属于行为型模式. 观察者模式: 类似我们在微信平台订阅了公众号 , 当它有新的文章发表后,就会推送给我们所有订阅的人. 我们作为订阅者不必每次都去查看这个公众号有没有新文章发布,公众号作为发布者会在合适时间通知我们

  • 原生js中ajax访问的实例详解

    原生js中ajax访问的实例详解 form表单中 登录名: 失去光标即触发事件 function createXmlHttp() { var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { try {// Internet Explorer xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (

  • js中Object.create实例用法详解

    1.用Object.create()方法创建新对象,并使用现有对象提供新对象的proto. 2.提供两个参数,第一个是新创建的原型对象,第二个是为新创建的对象添加属性的对象. 实例 // father 对象 let father = { name: 'father', friend: ['abby', 'bob'] } // 生成新实例对象 child1 let child1 = Object.create(father) // 更改值类型属性 child1.name = '修改了name' c

  • Kotlin 语言中调用 JavaScript 方法实例详解

    Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J

随机推荐