博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
轻松几句搞定【Javascript中的this指向】问题
阅读量:5214 次
发布时间:2019-06-14

本文共 3302 字,大约阅读时间需要 11 分钟。

this关键字在JavaScript中扮演了至关重要的角色,每次它的出现都伴随着它的指向问题,这也是很多初学者容易出错的地方。

不过,这篇文章将会带你一次性搞定this指向的问题,望能给大家提供帮助!


一、谁最终调用函数,this就指向谁!


 

这句话是需要牢记的口诀,将this的指向问题转换为分析确定函数最终调用者的问题,以下是对这句话的解释和补充:

            ① this指向谁,不应该考虑函数在哪里里声明的,而是应该考虑函数在哪调用;

            ② this指向的永远是对象,而不可能是函数。
            ③ this指向的对象叫做函数的上下文(context),也叫函数的调用者。

那么问题又来了,函数的最终调用者如何确定呢?我们先来看一个面试题:

阅读如下代码,输入的结果应该是?var length = 10function fn() {    alert(this.length)}var obj = {    length: 5,    method: function(fn) {        fn()   // ?          arguments[0]()   // ?      }}obj.method(fn);

试着确定一下,题干中函数的最终调用者是谁?有了答案的话我们继续往下看:


★★★   二、this指向的规律    :(跟函数的调用方式息息相关!)


           ① 通过 【 函数名() 】 调用的,this永远指向window;

            ② 通过 【 对象.方法 】调用的,this永远指向对象。obj.func();
            ③ 函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,this指向数组arr。
            ④ 函数作为window内置函数的回调函数使用,this指向window;
                  setTimeout() setInterval()等
            ⑤ 函数作为构造函数,使用new关键字调用,this指向新new出的对象。

针对以上的规律我们分别举例说明:

① 通过 函数名() 】 调用的,this永远指向window;

function func () {                console.log(this);            }            func();//函数名+()调用,this指向window

  ② 通过 【 对象.方法 】调用的,this永远指向对象。

var obj = {                name:"wq";                func:func;            }            obj.func();//通过对象.方法调用的,this永远指向对象。
Window.onclick = function  () {                document.getElementById("zz").onclick = function  () {                    func();//函数名+()调用,this指向window                }                document.getElementById("zz").onclick  = func;//广义对象  通过对象.方法调用的,this永远指向对象            }

③ 函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,this指向数组arr。

var arr [1,2,3,func,4,5,6]  arr[3]();//函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,this指向数组arr

④ 函数作为window内置函数的回调函数使用,this指向widow;

setTimeout(func,1000);//函数作为window内置函数的回调函数使用,this指向window;

 ⑤ 函数作为构造函数,使用new关键字调用,this指向新new出的对象。

var obj1 = new func()//函数作为构造函数,使用new关键字调用,this指向新new出的对象obj1。
var obj1 ={                name:"obj1",                arr:[func,1,2,3,4]            } obj1.arr[0]()//最终的调用者是数组。 setTimeout(obj1.arr[0],2000);//,作为内置函数进行调用,故this指向window;相当于setTimeout(func,2000);

在结合了相关实例对这几句话进行理解之后,我们再回过头来看一下上面的那道面试题:

阅读如下代码,输出的结果应该是?var length = 10function fn() {    alert(this.length)}var obj = {    length: 5,    method: function(fn) {        fn()   // ?   10        arguments[0]()   // ?   1    }}obj.method(fn);答案:fn() // 10  通过函数名()调用,this指向window,即全局变量length。      arguments[0]() // 1 函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,注意此时的数组是arguments,传入实参fn.

tips:

在JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。arguments非常类似Array,但实际上又不是一个Array实例。

arguments对象的长度是由实参个数而不是形参个数决定的。

 

最后我们再通过几道面试题来巩固下:

var fullname = 'John Doe';            var obj = {               fullname: 'Colin Ihrig',               prop: {                  fullname: 'Aurelio De Rosa',                  getFullname: function() {                     return this.fullname;                  }               }            };            console.log(obj.prop.getFullname());             // 函数的最终调用者 obj.prop                         var test = obj.prop.getFullname;            console.log(test());              // 函数的最终调用者 test()  this-> window                        obj.func = obj.prop.getFullname;            console.log(obj.func());             // 函数最终调用者是obj                        var arr = [obj.prop.getFullname,1,2];            arr.fullname = "JiangHao";            console.log(arr[0]());            // 函数最终调用者数组

如有错误,欢迎大家指正交流!谢谢!

 

转载于:https://www.cnblogs.com/wq1994/p/7672565.html

你可能感兴趣的文章
springboot定时任务
查看>>
win10安装网络适配器
查看>>
idea设置打开文件窗口个数
查看>>
maven设置阿里云仓库
查看>>
springboot备份mysql后发送邮件并删除备份文件,支持win和Linux
查看>>
idea更换项目取消直接在当前窗口打开,设置为询问
查看>>
idea设置创建类的注释模板
查看>>
查看Linux是CentOS还是Ubuntu
查看>>
查看Mysql是否开启binlog
查看>>
springboot获取上下文ApplicationContext
查看>>
【转】Ubuntu环境搭建svn服务器
查看>>
java有包名的调用没有包名的类,用反射
查看>>
svn客户端清空账号信息的两种方法
查看>>
springboot添加servlet的两种方法
查看>>
java的Array和List相互转换
查看>>
win7安装IIS
查看>>
idea设置内存大小
查看>>
springboot热部署JRebel插件
查看>>
java获取当前项目路径System.getProperty("user.dir")
查看>>
idea关闭sonarLint自动扫描
查看>>