为什么要使用this? 解决的问题?

可以先通过一个例子了解下

function speak(){var name = this.nameconsole.log("Hello I am --" + name)
}
var me = {name: 'a',speak: speak
}
var you = {name: 'b',speak: speak
}
me.speak()  //Hello I am -- a
you.speak()  //Hello I am -- b
复制代码

this可以在同一个执行环境中使用不同的上下文对象。它其实提供了一种更加优雅的方式来隐式“传递”一个对象引用,因此可以使API设计的更加简洁且易于复用。

定义:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

其实关于this的指向问题可以从函数的执行调用过程中理解,当一个函数被调用时,会创建一个活动记录(执行上下文)。这个记录会包含函数在哪里被调用、函数的调用方法、传入的参数等信息,this也是这里的一个属性。当函数被某个对象调用时可以理解为在函数调用的那一刻它被调用对象拥有。所以this指向调用其的对象。

对于this的指向问题,一般都是根据以上的解释去理解,虽然在一般的情况下这样的理解是不会有问题的,但是当在某些场景下这样的解释并不是很准确,所以会让人感觉一直琢磨不透的感觉。今天可以就不同情况展开讨论下this指向的问题。看看下面的打印结果会是什么

// 例子1
function test(){var a = 10;console.log(this.a);console.log(this);
}
test();
// 例子二
var b = 10;
var o = {b: 20,fn:function(){console.log(this.b); }
}
o.fn();
复制代码

按照上面的定义this最终指向的是调用它的对象,这里的函数test实际是被Window对象所点出来的。所以例子1中的this指向的是windows。在例子2中函数的执行是通过o.fn()调用的,所以this的指向的当然是对象o了。这两个例子可以验证上面的定义,但是还是不够准确的。

// 例子三
var b = 10;
var o = {b: 20,fn:function(){console.log(this.b); }
}
window.o.fn();
复制代码

此时打印的应该是什么呢?这段代码和上面的那段代码几乎是一样的,但是这里的this为什么不是指向window,如果按照上面的理论,最终this指向的是调用它的对象,在此处就显得不是很准确了。所以关于函数中this的指向其实是可以分为三种情况的

  • 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window
  • 如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
  • 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,这就可以解释例子三中的this不是指向window了

那么以下的打印结果又应该是什么?

// 例子4
var o = {a:10,b:{a:12,fn:function(){console.log(this.a); console.log(this);}}
}
var j = o.b.fn;
j();
复制代码

此处的this指向的是window,其实这里只需要理解清楚一句话"this永远指向的是最后调用它的对象",也就是看它执行的时候是谁调用的,例子4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和例子3是不一样的,例子3是直接执行了fn。所以说,那例子5中的打印结果又应该是什么呢?

// 例子5
function foo() { console.log( this.a );
}
var obj = { a: 2,foo: foo
};
var bar = obj.foo; // 函数别名!
var a = "xxxxx"
bar();
复制代码

不同情况下this的使用

1.构造函数版this

// 例子6
function Fn(){this.user = "lh";
}
var a = new Fn();
console.log(a.user);
复制代码

这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象Fn中会有user,因为已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

!当this遇上return时

// 例子7
function fn()
{  this.user = 'lh';  return {};
}
var a = new fn;
console.log(a.user);// 例子8
function fn()
{  this.user = 'lh';  return function(){};
}
var a = new fn;  console.log(a.user)// 例子9
function fn()
{  this.user = 'lh';  return 1;
}
var a = new fn;
console.log(a.user);
复制代码

由上可知,如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

2.箭头函数中的this

var x=11;
var obj={x:22,say:()=>{console.log(this.x);}
}
obj.say();
复制代码

箭头函数不是通过function关键字定义的,也就不遵循以上的this规则,而是“继承”外层作用域中的this指向。箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定。所谓的定义时候绑定,就是this是继承自父执行上下文!!中的this,比如这里的箭头函数中的this.x,箭头函数本身与say平级以key:value的形式,也就是箭头函数本身所在的对象为obj,而obj的父执行上下文就是window,因此这里的this.x实际上表示的是window.x,因此输出的是11。

改变this指向的几种方法(apply,call, bind)

var a = {user:"lh",fn:function(){console.log(this.user);}
}
var b = a.fn;
b();
复制代码
  • 此时要改变this的指向,可以通过call方法
var a = {user:"lh",fn:function(){console.log(this.user);}
}
var b = a.fn;
b.call(a);
复制代码

通过在call方法,给第一个参数添加要把b添加到哪个环境中,也就是说,this就会指向那个对象。 call方法除了第一个参数以外还可以添加多个参数,如下

var a = {user:"lh",fn:function(p1, p2){console.log(this.user)console.log(p1+p2)}
}
var b = a.fn;
b.call(a, 1, 3)
复制代码
  • 使用apply()方法,改变this指向的效果和call相似,在于他们传递的参数格式不同,第二个参数必须是一个数组,如下:
var a = {user:"lh",fn:function(p1, p2){console.log(this.user)console.log(p1+p2)}
}
var b = a.fn;
b.apply(a, [1, 3])
复制代码

!当call和apply的第一个参数写的是null,那么this指向的是window对象

  • bind()方法

bind()方法也可用来改变this的指向,但是和call,apply方法在用法上有区别,如下:

var a = {user:"lh",fn:function(){console.log(this.user);}
}
var b = a.fn;
b.bind(a);
复制代码

此时发现并不打印任何的结果,这是因为bind方法返回的是一个修改过后的函数,此时执行conole.log(b.bind(a))会得到的结果是:


ƒ () {console.log(this.user);
}
复制代码

call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。并且也是可以像call和apply一样传递参数

JS 中 this 的指向相关推荐

  1. 理解js中this的指向

    彻底理解js中this的指向 JavaScript 的 this 指向问题深度解析 转载于:https://www.cnblogs.com/jeacy/p/6509616.html

  2. JS中this的指向

    JS中this的指向,this是js中的一个关键字 1.this的指向有这四种情况 1. 在普通的函数中,this指向全局对象window 2.在构造函数中,this指向创造出来的实例 3.对象的方法 ...

  3. 简述JS中THIS的指向?

    这里是修真院前端小课堂,每篇分享文从 八个方面深度解析前端知识/技能,本篇分享的是: [简述JS中THIS的指向?] 大家好,我是IT修真院武汉分院web第16期的学员孟晨,一枚正直纯洁善良的web程 ...

  4. 彻底理解js中this的指向

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  5. 随笔——js中的this指向,apply()与 call()

    js中apply和Math.max()函数(原文) apply() Function.apply() 是JS的一个OOP特性,一般用来模拟继承和扩展this的用途,对于上面这段代码,可以这样去理解: ...

  6. 理解js中的this指向以及call,apply,bind方法

    <script> function a(){var user = "追梦子";console.log(this.user); //undefinedconsole.lo ...

  7. JS中this的指向与改变this指向的三个方法

    目录 一.this指向的分类 1.全局函数的调用 2.对象中函数的调用 3.setTimeout与setInterval中的this 4.事件绑定中的this 5.箭头函数中的this 6.构造函数中 ...

  8. js中this的指向问题

    JS 面试题: var obj = { foo: function(){ console.log(this) } } var bar = obj.foo obj.foo() // 打印出的 this ...

  9. js中的 this指向面试题

    在普通函数中this指向window function test(){this.x=1;console.log(this); //window }; test(); 在对象下的this指向是对象本身, ...

最新文章

  1. Android WebView 与 JS 交互
  2. 欧氏距离 vs 马氏距离
  3. SAP S/4HANA 物料搜索(Material Search) 页面的外观和背后调用的 OData 服务
  4. socketio mysql_Golang + Socket.io
  5. python怎么设置notebook_JupyterNotebook设置Python环境的方法步骤
  6. 产品读书《大败局 I》 《大败局II》
  7. boost升压电路解析
  8. 3D动态视频屏保热带鱼水族馆
  9. 黑莓7290无信号问题
  10. 数据中心网络图怎么画?几步教会你
  11. dva 的一些特殊的写法
  12. 视觉心理物理学(2)matlab与ptb3
  13. 思维导图|kotlin入门基础语法
  14. NLS_LANG与NLS_LANGUAGE的区别
  15. 基数排序——多关键字排序(MSD/LSD)以及链式基数排序
  16. python怎么返回上一步操作_一步一步教你如何用python操作mysql
  17. 兼容火狐、谷歌等主流浏览器的万年历
  18. 深入浅出HTTPS工作原理 1
  19. 2015百度之星资格赛解题报告
  20. Ananagrams(sort+map) UVA - 156 统计字谜

热门文章

  1. [译] Redux 有多棒?
  2. 浪潮英特尔在德国发布KEEP升级计划 用户可提前体验英特尔KNM
  3. Android动态权限管理模型(4.3-6.0)
  4. ssh整合问题总结--使用struts2+Ajax+jquery验证用户名是否已被注册
  5. Mysql数据库主从搭建
  6. paip.提升效率--调试--日志系统日志参数含义---python
  7. OC实例变量和属性-@synthesize与@property
  8. windows使用ssh2远程登陆ubuntu
  9. python数据库管理实例_西游之路——python全栈——学员管理实例之数据库设计
  10. Kali Linux常用服务配置教程安装及配置DHCP服务