我对JavaScript中this的一些理解
因为日常工作中经常使用到this
,而且在JavaScript中this
的指向问题也很容易让人混淆一部分知识。
这段时间翻阅了一些书籍也查阅了网上一些资料然后结合自己的经验,为了能让自己更好的理解this
,进而总结一篇文章。
#this 是什么
this
是 JavaScript 语言的一个关键字。它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。
实际是在函数被调用时才发生的绑定,也就是说this
具体指向什么,取决于你是怎么调用的函数。
#this 指向的四种情况
这四种情况基本涵盖了JavaScript中常见的this
指向问题
#1. 全局的函数调用,this指向window
var a = 1;
function fn() {
console.log(this.a);
}
fn(); // 1
这种 情况下的this
其实就是window
对象,这个很好理解。 但是还有一种情况,就是匿名函数的this
也会指向window
。
var a= 'window';
var obj={a: 'object'}
obj.fn=function(){
console.log(this.a);//Object
+function(){
console.log(this.a)//window
}()
}
obj.fn()
匿名函数的执行环境具有全局性,因此它的this
对象通常指向windows。
如果对此有疑惑,可以看知乎上的答案:知乎 - 匿名函数的this指向为什么是window?
#2. 作为对象方法的调用,this指向该对象
var a ='window'
var obj={
a: 'object',
fn: function(){
console.log(this.a);
}
}
obj.fn(); // object
当函数作为某个对象的方法调用时,this
就指这个函数所在的对象。
#3. 作为构造函数调用,this指向实例
function fn() {
this.x = 1;
}
var obj = new fn();
console.log(obj.x) // 1
构造函数中的this
,在通过new
之后会生成一个新对象,this就指这个新对象。
对new
有疑问的话,可以看 冴羽的博客 JavaScript深入之new的模拟实现
#4. 使用call/apply/bind调用, this指向第一个参数
var obj1={
a: 'boj1'
}
var obj2={
a: 'obj2'
}
var obj3={
a: 'obj3'
}
function fn(){
console.log(this.a);
}
// apply
fn.apply(obj1);// 'obj1'
// call
fn.call(obj2);// 'obj2'
// bind
var fnBind= fn.bind(obj3);
fnBind();// 'obj3'
call/ apply / bind
都有一个共同的特点,就是改变this
的指向,使用这种方法可以把别人的方法拿过来用到自己身上。
第一个参数为 null
的时候,视为指向 window
.
var a='window'
var obj={
a: 'boj',
fn: function (){
console.log(this.a);
}
}
obj.fn.call(null);// 'window'
在这里如果是obj.fn()
调用的fn()
方法,this
应该指向obj
没错。 但是因为call(null)
的存在,改变了指向,所以this
指向了window
。
#深入理解
正因为比较难理解,所以this
指向也是面试时最容易遇到的问题,比如下面这道我曾遇到的一个面试题:
var length = 10;
function fn(){
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn){
fn();//10
arguments[0]();//2 这里的this指向的arguments,所以获取的是arguments.length
}
};
obj.method(fn, 1);
在这道题里,不仅考察了对this
熟悉程度,还考察了函数的传参形式、作用域、以及arguments
这种特殊的数组的理解。
只有真正理解了这些才能正确的判断this
究竟指向了谁。
所以,只有对JavaScript
中的各项知识点深入理解,才会对this
的概念越加清晰。
参考:
- 提取数字——字符串、正则面试题
- 【盟友分享】如何快速获取Chromium源码和编译
- .NET中的密钥加密
- 数据挖掘工程师笔试及答案
- 各大公司移动端页面 - 导航的实现
- JavaScript 运行机制之执行顺序详解
- Math对象面试题目
- Highcharts AJAX JSON JQuery 实现动态数据交互显示图表 柱形图
- 企业支付宝账号开发接口教程--JAVA-UTF-8(实际操作------SpringMVC+JSP)
- 用pandas 进行投资分析
- 【专业技术】android 应用程序如何获取root权限
- Nginx+Keepalived(双机热备)搭建高可用负载均衡环境(HA)
- SpringMVC+MongoDB+Maven整合(微信回调Oauth授权)
- ZeroClipboard实现多个浏览器兼容的复制文本到剪贴板的功能
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android自定义View圆形和拖动圆、跟随手指拖动效果
- Android开发之OkHttpUtils的具体使用方法
- Xshell5连接虚拟机中的Linux的方法以及失败原因解决
- Android 多线程的实现方法总结
- Android编程之SQLite数据库操作方法详解
- 浅谈android组件化之ARouter简单使用
- Android ScrollView实现下拉弹回动画效果
- Android实现用文字生成图片的示例代码
- Android bindservice失败解决方法
- Android 悬浮窗权限各机型各系统适配大全(总结)
- Android中Fragment相互切换间不被回收的实现方法
- Android手机管理工具类详解
- 通过代码学Sutton强化学习第四章动态规划
- android通过okhttpClient下载网页内容的实例代码
- Android自定义键盘的实现(数字键盘和字母键盘)