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

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


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


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

① this指向谁,不应该考虑函数在哪里里声明的,而是应该考虑函数在哪调用;
            ② this指向的永远是对象,而不可能是函数。
            ③ this指向的对象叫做函数的上下文(context),也叫函数的调用者。

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

阅读如下代码,输入的结果应该是?
var length = 10
function 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 = 10
function 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]());
// 函数最终调用者数组

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

轻松几句搞定【Javascript中的this指向】问题的更多相关文章

  1. 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )

    变量:  存储数据的容器     1.声明        var   2.作用域       全局变量. 局部变量. 闭包(相对的全局变量):   3.类型         a.基本类型(undefi ...

  2. 面试大总结:Java搞定面试中的链表题目总结

    package LinkedListSummary; import java.util.HashMap; import java.util.Stack; /** * http://blog.csdn. ...

  3. 面试大总结之二:Java搞定面试中的二叉树题目

    package BinaryTreeSummary; import java.util.ArrayList; import java.util.Iterator; import java.util.L ...

  4. (转)面试大总结之一:Java搞定面试中的链表题目

    面试大总结之一:Java搞定面试中的链表题目 分类: Algorithm Interview2013-11-16 05:53 11628人阅读 评论(40) 收藏 举报 链表是面试中常出现的一类题目, ...

  5. 14招搞定JavaScript调试

    14招搞定JavaScript调试 译者按: 很多时候,大家可能只是依靠console.log来调试JavaScript代码,这样做的局限性不言而喻,这篇博客将教你几招实用的调试技巧. 原文: The ...

  6. 轻松八步搞定Cacti配置安装(原创视频)

    轻松八步搞定Cacti配置安装 1.安装web server $sudo apt-get install apache2 验证 http://localhost 2.$sudo apt-get ins ...

  7. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

  8. 转:彻底搞清楚javascript中的require、import和export

    原文地址:彻底搞清楚javascript中的require.import和export   为什么有模块概念 理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块. 但是,Ja ...

  9. javascript中this的指向

    作为一个前端小白在开发中对于this的指向问题有时候总是会模糊,于是花时间研究了一番. 首先this是JS的关键字,this是js函数在运行是生成的一个内部对象,生成的这个this只能在函数内部使用. ...

随机推荐

  1. unix下的文件和目录详解以及操作方法

    前言:unix下一切东西都是文件,一共有7种不同的文件,前一篇博客已经讲解的很清楚了,不懂的可以看看这里.当然,博主知道有些朋友比忙,没时间看,那我就简单点讲讲这7中文件都有哪些吧. 文件类型包括在s ...

  2. MPLS VPN随堂笔记3

    跨域 ASBR之间运行MPBGP 1.配置AS内部IGP保证环回口互相可达,同时建立LDP邻居 (优先启用 mpls label rang 16 100)方便查看实验现象 2.配置PE1-PE2 PE ...

  3. windows下使用密钥登录Linux及xshell代理转发

    1.密钥登录原理 一般我们使用xshell访问远程主机(Linux主机)时,都是先请管理员给我们开一个账户,即为我们设置一个一个用户名和对应的密码,然后我们就可以使用下面的方式登录到远程主机了: 在这 ...

  4. 第二次项目冲刺(Beta阶段)5.20

    1.提供当天站立式会议照片一张 会议内容: ①检查前一天的任务情况,心得分享以及困难分析. ②制定新一轮的任务计划. 2.每个人的工作 (1)工作安排 队员 今日进展 明日安排 王婧 #42文件分类改 ...

  5. 201521123075 《Java程序设计》第1周学习总结

    1. 本周学习总结 (1)Java不仅是程序语言,还是一种标准规范,代表着解决问题的方案.Java是一个面向对象的编程语言,熟悉后相对于c++更方便,其一大特色就是能够跨平台运行. (2)Java发展 ...

  6. 201521123034 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前 ...

  7. java课程设计(Calculator) 201521123027 陈龙

    1.团队博客链接 http://www.cnblogs.com/DevilRay/p/7064482.html 2.个人负责模块或任务说明 (1)主函数的编写: (2)加减乘除运算的实现: (3)求倒 ...

  8. ROS学习记录(四)————怎样建立一个package包?

    功能包是什么? 英文表述package,我可没有在炫英文啊,我的英文很烂的,只是在提醒大家,在ROS系统中,这个词使用的频率非常之高,你必须记住它,要不就没法正确的看懂信息.言归正传,package是 ...

  9. bootStrap事例代码

    最近在学bootStrap,在慕课网中有这么一个例子-.感觉以后会用到这些代码.保存起来. <!DOCTYPE html> <html lang="zh-cn"& ...

  10. python之time模块

    from time import * ''' class struct_time(tuple): pass ''' tuple1 = (, , , , , , , , ) s = struct_tim ...