轻松几句搞定【Javascript中的this指向】问题
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指向】问题的更多相关文章
- 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )
变量: 存储数据的容器 1.声明 var 2.作用域 全局变量. 局部变量. 闭包(相对的全局变量): 3.类型 a.基本类型(undefi ...
- 面试大总结:Java搞定面试中的链表题目总结
package LinkedListSummary; import java.util.HashMap; import java.util.Stack; /** * http://blog.csdn. ...
- 面试大总结之二:Java搞定面试中的二叉树题目
package BinaryTreeSummary; import java.util.ArrayList; import java.util.Iterator; import java.util.L ...
- (转)面试大总结之一:Java搞定面试中的链表题目
面试大总结之一:Java搞定面试中的链表题目 分类: Algorithm Interview2013-11-16 05:53 11628人阅读 评论(40) 收藏 举报 链表是面试中常出现的一类题目, ...
- 14招搞定JavaScript调试
14招搞定JavaScript调试 译者按: 很多时候,大家可能只是依靠console.log来调试JavaScript代码,这样做的局限性不言而喻,这篇博客将教你几招实用的调试技巧. 原文: The ...
- 轻松八步搞定Cacti配置安装(原创视频)
轻松八步搞定Cacti配置安装 1.安装web server $sudo apt-get install apache2 验证 http://localhost 2.$sudo apt-get ins ...
- 来一轮带注释的demo,彻底搞懂javascript中的replace函数
javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...
- 转:彻底搞清楚javascript中的require、import和export
原文地址:彻底搞清楚javascript中的require.import和export 为什么有模块概念 理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块. 但是,Ja ...
- javascript中this的指向
作为一个前端小白在开发中对于this的指向问题有时候总是会模糊,于是花时间研究了一番. 首先this是JS的关键字,this是js函数在运行是生成的一个内部对象,生成的这个this只能在函数内部使用. ...
随机推荐
- C# xml增删查改
C# XML XmlDocument 添加命名空间: using System.Xml; 定义公共对象: XmlDocument xmldoc ; XmlNode xmlnode ; XmlEleme ...
- 【Alpha阶段】第一次Scrum Meeting!
每日任务 1.本次会议为第一次 Meeting会议: 2.本次会议在中午12:30,在第五社区5号楼楼下,召开本次会议为30分钟讨论接下来的任务: 一.今日站立式会议照片 二.每个人的工作 (有wor ...
- 团队作业8——Beta 阶段冲刺1st day
一.今日站立式会议照片 二.每个人的工作 (1) 昨天已完成的工作: 今天是冲刺的第一天,昨天完成的是团队成员任务的分配 (2) 今天计划完成的工作: 界面的完善 (3) 工作中遇到的困难: 对于界面 ...
- 201521123082 《Java程序设计》第7周学习总结
201521123082 <Java程序设计>第7周学习总结 标签(空格分隔): Java 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1. ...
- 团队作业8——第二次项目冲刺(Beta阶段)Day7——5.26
展开圆桌式会议: 会议内容:1.汇总BETA阶段的成果.2.针对BETA阶段的大家的获得的收获进行了讨论.3.对整个团队项目的过程进行了总结.每个人的工作分配: 队员 今日任务 贡献比 林燕 做最后测 ...
- 201521123097《Java程序设计》第三周学习总结
1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...
- 201521123121 《Java程序设计》第2周学习总结
1. 本周学习总结 通过分析数据所需要占用的内存长度来决定java的类型,其中主要分为基本类型和长类型. 基本类型主要分为五个方面:整数(short=2字节:int=4字节:long=8字节):字节( ...
- 201521123117 《Java程序设计》第10周学习总结
1. 本周学习总结 2.2. 书面作业 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? 只要try执行了之后,finall ...
- web前端 学习线路
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- 小甲鱼:Python学习笔记002_数组_元组_字符串
创建普通数组 >>> member=["山东黄金","九阳股份"] >>> member ['山东黄金', '九阳股份'] ...