JS中的this指向问题(详解)

文章详细介绍了JavaScript中的严格模式,包括开启方式和其目的。然后探讨了不同场景下this的指向,如全局环境、普通函数(严格和非严格模式)、对象方法、箭头函数以及构造函数中的行为。此外,还讨论了如何通过call()、apply()和bind()方法改变this的指向。
摘要由CSDN通过智能技术生成

在开始之前我们先来了解一下什么是严格模式。

1. 什么是严格模式

  • JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。

  • ES5 的严格模式是采用具有限制性 JavaScript变体的一种方式,即在严格的条件下运行 JS 代码。

  • 严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。

  • 严格模式对正常的 JavaScript 语义做了一些更改:

    1、消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
    2、消除代码运行的一些不安全之处,保证代码运行的安全。
    3、提高编译器效率,增加运行速度。
    4、禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:class,enum,export, extends, import, super 不能做变量名。

1.1 开启严格模式

严格模式可以应用到整个脚本或个别函数中,可以将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况。

情况一 :为脚本开启严格模式

有的 script 脚本是严格模式,有的 script 脚本是正常模式,这样不利于文件合 并,所以可以将整个脚本文件放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他 script 脚本文件。

(function (){ 
    //在当前的这个自调用函数中有开启严格模式,当前函数之外还是普通模式 
    	"use strict"; 
   		let arr = [] 
})(); 
//或者 
<script> 
    "use strict"; //当前script标签开启了严格模式 
</script>
<script> 
    //当前script标签未开启严格模式 
</script>

情况二: 为函数开启严格模式

要给某个函数开启严格模式,需要把“use strict”; (或 ‘use strict’; ) 声明放在函数体所有语句之前。

function fn(){ 
    "use strict";
    
}
//当前fn函数开启了严格模式

注:不管哪种情况下,"use strict"都必须写在第一行才能开启严格模式

this 是 JavaScript 最具“魅惑”的知识点,不同的应用场合 this
的取值可能会有意想不到的结果,在此我们对以往学习过的关于【 this 默认的取值】情况进行归纳和总结。

2、 全局环境下的this指向

在全局作用域下,this始终指向全局对象window,无论是否为严格模式

那么了解完什么是严格模式后,我们就开始this指向之旅吧。

console.log(this);//window

在这里插入图片描述
congsole.log()完整的写法是window.console.log(),我们默认会将它省略,window调用了console.log()方法,所以此时this指向window。

3、普通函数的this指向

普通函数的调用方式决定了 this 的值,即【谁调用 this 的值指向谁】
不过普通函数内的this分为两种情况,严格模式下和非严格模式下。

3.1 严格模式下:

 		function fn() {
            'use strict'
            console.log(this);
        }
        fn()
        window.fn()
        //函数表达式
        const fn1 = function f() {
            console.log(this);
        }
        fn1()

在这里插入图片描述

直接fn( )调用函数,this指向undefined
window.fn()调用函数this指向window。因此,在严格模式下, 我们对代码的的调用必须严格的写出是谁调用了这个函数,不可以有省略或者说简写。

注: 在函数表达式中,this也是指向undefined,
并且不能采用window.fn1(),因为window里面没有这个函数。

3.2 非严格模式下:

		function fn() {
            console.log(this);
        }
        fn()
        在函数表达式中,this也是指向window
        const fn1 = function f() {
            console.log(this);
        }
        fn1()

在这里插入图片描述

4、 对象中的this指向

对象内部方法的this指向调用这些方法的对象,也就是谁调用就指向谁。

	const obj = {
            name: '张三',
            age: 18,
            walk: function () {
                console.log(this.name);
            }
        }
        obj.walk()//张三

在这里插入图片描述
调用obj.walkl()方法,返回值为张三,说明此时this指向obj

5、箭头函数中的this

箭头函数中的 this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this !

1、箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的
2、箭头函数中的this引用的就是最近作用域中的this
3、向外层作用域中,一层一层查找this,直到有this的定义

	<div>11</div>
    <script>
        document.querySelector('div').addEventListener('click',function() {
            console.log(this);
        })
        document.querySelector('div').addEventListener('click',()=> {
            console.log(this);
        })
    </script>

在这里插入图片描述
我们定义一个div标签,给他注册点击事件,使用普通函数的方法,所以则指向div,
在普通函数里面谁调用就指向谁

箭头函数里面没有this,所以向外层作用域中,一层一层查找this,直到有this的定义。最外层是window,所以指向的是window。

5、 构造函数中的this指向

构造函数中的this是指向实例。

 		function Fn(name,age) {
            this.name = name
            this.age = age
        }
        const fn = new Fn('张三',18)
        console.log(fn.name);
        console.log(fn.age);

在这里插入图片描述
由上图可以看出,构造函数中的this指向构造函数下创建的实例。

严格模式下,如果构造函数不加new调用, this 指向的是undefined
如果给他赋值则会报错。

7、改变this指向的方法

有时候,我们需要改变this的值,这时就可以使用call( )、apply( )、或bind( )等方法。

7.1 call()和apply()方法

call()和apply()方法可以用来改变函数中this的值,并立即调用该函数。
两者的区别在于传参方式的不同,call()方法传参以逗号相隔,apply()方式传参以数组的形式。
我们来看段小例子理解一下:

		const obj = {
            name: '张三'
        }
        function fn(x, y) {
            console.log(this, x, y);
        }
        fn(1, 2)
        fn.call(obj, 1, 2)//call方法
        fn.apply(obj, [1, 2])//apply方法

在这里插入图片描述
默认情况下fn()中的this是指向window,通过call()和apply()方法将this指向对象obj。

7.2 bind()方法

bind()方法可以用来改变函数中this的值,并返回一个原拷贝函数,也就是一个新的函数,不同于 call()和apply()方法,它不会立即调用该函数,所以在很多时候用的最多的就是bind()方法。

 		const obj = {
            name: '张三'
        }
        function fn(x, y) {
            console.log(this, x, y);
        }
        fn(1, 2)
        const binds = fn.bind(obj, 1, 2)
        binds()

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方青云、

你的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值