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. Java web servers 间是如何实现 session 同步的

     Java web servers 间是如何实现 session 同步的 有一个多月的时间没有更新博客了,今天终于忙里偷闲,可以把近期的收获总结一下. 本文是关于Java web servers 之间 ...

  2. java.lang.OutOfMemoryError 解决程序启动内存溢出问题

    java.lang.OutOfMemoryError: Java heap space Myeclipse里面部署的java web项目,浏览器访问的时候出现错误: type Exception re ...

  3. 团队作业4——第一次项目冲刺(Alpha版本) 2

    一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 1.完成了大部分查重算法的书写. 余弦查重算法 2.其他非主页面的部分设计. 查重过程的显示页面 四.困难与问题 1.算法是程 ...

  4. 201521044091 《java程序设计》第八周学习总结

    本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容.1.2 选做:收集你认为有用的代码片段 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1)1.1 实验 ...

  5. 201521123060《Java程序设计》第2周学习总结

    1. 本周学习总结 a.进一步熟悉了Eclipse的使用和java程序的编写: b.学习了java数据的基本类型:整数类型,浮点类型等: c.学习了算数运算符,赋值运算符,位运算符,关系运算符,逻辑运 ...

  6. 201521044091 java 第一周总结

    1.本周学习总结 (1)第一次开始接触java语言,有些用法还是和c和c++有点差异,需要不断去学习 (2)java其实不仅仅一种高级语言,它包括的还有它的整套体系. 2. 书面作业 1.为什么jav ...

  7. Java课程设计—象棋

    1. 团队名称.团队成员介绍 团队名称:WY 团队成员: 吴慧婷[组长] 201521123094 网络1514 姚佳希 201521123042 网络1512 2 项目git地址 Java课程设计 ...

  8. 201521123056 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1. finally 题目4-2 1.1 截图你的提交结果( ...

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

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 Q1:常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何 ...

  10. 201521123053《Java课程设计》第十四周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 知识点: 创建表的命令有若干行,如果中间某行输入错误,不能修改:可以使用记事本现将命令输入,然后复制粘贴到mys ...