php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 618|回复: 0

秒懂JS的this指向问题

[复制链接]

2670

主题

2677

帖子

9495

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
1
威望
0
积分
6703
贡献
0
注册时间
2021-4-14
最后登录
2024-5-15
在线时间
674 小时
QQ
发表于 2022-1-12 13:00:15 | 显示全部楼层 |阅读模式
一句话概括this指向:谁调用this就指向谁
这句话可能太过广义,那么请看以下的各种this指向场景

1.箭头函数(=>)
        箭头函数this的指向不会发生改变,也就是说在创建箭头函数时就已经确定了它的this的指向了;它的指向永远指向箭头函数外层的 this。
[mw_shl_code=applescript,true]        function fn1() {
            console.log(this);

            let fn2 = () => {
                console.log(this);
            }
            fn2(); //this->window
        }
        fn1();//this->window

//因为fn1函数中this的指向是window,所以fn2箭头函数this指向fn1函数也就是间接指向window
[/mw_shl_code]

2.直接调用
在函数被直接调用时,this 将指向全局对象。在浏览器环境中全局对象是 Window,在 Node.js 环境中是 Global。

全局作用域中:this永远指向window

函数作用域中:

如果函数直接被调用  this指向window  函数名()      
被对象的对象.属性()调用  函数中的this指向这个对象
[mw_shl_code=applescript,true]
        var obj = {

            fn: function fn1() {
                console.log(this);
            },
        }
        obj.fn(); //this->obj[/mw_shl_code]
3.对象.属性()调用
        这里说的this指向就是上文中代码中的例子,有兴趣可以自行多尝试一下此场景中的this

4.new
        当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。

可能你会有所疑问:“如果使用 new 关键调用箭头函数,是不是箭头函数的 this 就会被修改呢?”。

我们可以在控制台尝试一下:
[mw_shl_code=applescript,true]fun = () => {}
new fun() // throw error[/mw_shl_code]
从控制台中可以看出,箭头函数不能当做构造函数,所以不能与 new 一起执行。

5.bind
        bind 是指 Function.prototype.bind()->原型里的方法

多次 bind 时只认第一次 bind 的值

例子:
[mw_shl_code=applescript,true]function fn() {
  console.log(this)
}
fn.bind(1).bind(2)() // 1[/mw_shl_code]
注意:箭头函数中 this 不会被修改

[mw_shl_code=applescript,true]fun = () => {
  // 这里 this 指向取决于外层 this
  console.log(this)
}
fun.bind(1)() // Window[/mw_shl_code]
bind 函数中 this 不会被修改

[mw_shl_code=applescript,true]function func() {
  console.log(this)
}
boundFunc = func.bind(1)
boundFunc.apply(2) // 1 bind优先[/mw_shl_code]

总结:将参数一一进行传递,在被函数调用时不会立马执行函数,返回有一个新函数,新函数中的this指向改变,不影响原来的函数的this指向

6.apply 和 call
        作用:改变this指向

        区别:调用时传递参数形式不同

call:将参数一一进行传递(改变函数中的this指向 指向第一个参数;并且执行函数)
apply:将参数用数组的形式传递(改变函数中的this指向 指向第一个参数;并且执行函数)
使用:
[mw_shl_code=applescript,true]function Person(name,age){
        this.name = name;
        this.age = age;
}
var person = new Person("xiaoming",100);
var obj = {}
Person.apply(obj,['xiaoming',300]);//Person {name: 'xiaoming', age: 100};
Person.call(obj,'xiaozhang',300);//Person {name: 'xiaoming', age: 100};
console.log(person)[/mw_shl_code]
箭头函数中 this 不会被修改

[mw_shl_code=applescript,true]func = () => {
  // 这里 this 指向取决于外层 this
  console.log(this)
}
func.apply(1) // Window[/mw_shl_code]
7.不在函数里        
        不在函数中的场景,可分为浏览器的 <script /> 标签里,或 Node.js 的模块文件里。

在 <script /> 标签里,this 指向 Window。
在 Node.js 的模块文件里,this 指向 Module 的默认导出对象,也就是 module.exports
非严格模式
严格模式是在 ES5 提出的。在 ES5 规范之前,也就是非严格模式下,this 不能是 undefined 或 null。所以在非严格模式下,通过上文各种场景得知,如果得出 this 指向是 undefined 或 null,那么 this 会指向全局对象。在浏览器环境中全局对象是 Window,在 Node.js 环境中是 Global。

        非严格模式代码我就不运行了结果了,感兴趣的朋友可以自行复制打印在控制台看看运行结果~~~
[mw_shl_code=applescript,true]function fn() {
  console.log("function fn:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

fn()

fn.bind(null)()

fn.bind(undefined)()

fn.bind().bind(2)()

fn.apply()[/mw_shl_code]





上一篇:Html+CSS+JS轮播图:手动轮播,自动轮播
下一篇:小程序实现数据双向绑定
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|php中文网 | cnphp.com ( 赣ICP备2021002321号-2 )

GMT+8, 2024-5-17 11:02 , Processed in 0.153560 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

申明:本站所有资源皆搜集自网络,相关版权归版权持有人所有,如有侵权,请电邮(fiorkn@foxmail.com)告之,本站会尽快删除。

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