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. 关于js中单双引号以及转义符的理解

    关于js中单引号(')和双引号(")的使用以及转义的理解 这几天一直在画页面,身为开发人员的我之所以要画页面是因为当前项目中的页面上所有的东西都是从数据库中取得的,也就是动态的,类似于我们设 ...

  2. [转载]PS各个工具的字母快捷键和英文全名

    原文地址:PS各个工具的字母快捷键和英文全名作者:Tycho     选框-Marquee(M)     移动-move(V)     套索-Lasso(L)     魔棒-Wand(W) 喷枪-in ...

  3. 201521123026 《Java程序设计》第6周学习总结

    1. 本章学习总结 请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结 2. 书面作业 Q1.clone方法 1.1 Object对象中的clone方法是被prot ...

  4. 201521123090《JAVA程序设计》第二周学习总结

    1. 本章学习总结 java基本数据类型 String类对象使用 枚举类型及switch分支 容器的概念 2. 书面作业 Q1.使用Eclipse关联jdk源代码(截图),并查看String对象的源代 ...

  5. update:我的Emacs配置文件

    ;;设置字体用的  防止中文变成无法识别的框框 (set-default-font "Consolas-11") (set-fontset-font "fontset-d ...

  6. 201521123065《java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 1.流的划分:输入流:字节流(InputStream).字符流(reader): 输出流:字节流(Output ...

  7. Thinkphp3.2结合phpqrcode生成二维码(含Logo的二维码),附案例

    首先,下载phpqrcode,将其解压到项目ThinkPHP\Library\Vendor目录下.Index_index.html(模板可自行配置) <form action="{:U ...

  8. MyEclipse中Source Folder,package,folder的区别

    1.在eclipse下,package, source folder, folder都是文件夹. 但它们有区别如: 2. package:当你在建立一个package时,它自动建立到source fo ...

  9. Android 之xml解析

    HTTP网络传输中的数据组织方式有三种方式:1.HTML方式2.XML方式 3.JSON方式 XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言) XML是Internet环境 ...

  10. 凸包GiftWrapping GrahamScan 算法实现

    开始 游戏内有需求做多边形碰撞功能,但是接入box2d相对游戏的需求来说太重度了.所以准备自己实现碰撞. 确定多边形,必然要用到凸包的算法.在github上也找到了一些lua实现,但是这里的算法没有考 ...