解决this指代的三种常用方法

JavaScript语言的this对象一直是一个令人头痛的问题。在这里,我们以一个简单小例子来为大家讲解!

原文链接:https://editor.csdn.net/md/?articleId=105790363

直接上代码:

class Animal {constructor() {this.type = 'animal';}says(say) {   setTimeout(function() {console.log(this.type + ' says ' + say);}, 1000);}
}
var animal = new Animal();
animal.says('hello');
//输出结果:undefined says hello
//注意:这里的this指向的是全局作用域,所以是undefined

分析原因:一般情况下setTimeout()的this指向window或global对象;而当使用类的方法时,需要this指向类实例,以下三种方法可以将this绑定到回调函数来管理实例

解决方法一(传统):赋值, 将this传给self,再用self来指代this
class Animal {constructor() {this.type = 'animal';}says(say) {var self = this;setTimeout(function() {console.log(self.type + ' says ' + say);}, 1000);}
}
var animal = new Animal();
animal.says('hello');
//输出结果:animal says hello
解决方法二(ES5):bind(this)
class Animal {constructor() {this.type = 'animal';}says(say) {setTimeout(function() {console.log(this.type + ' says ' + say);}.bind(this), 1000);}
}
var animal = new Animal();
animal.says('hello');
//输出结果:animal says hello
解决方法三(ES6):箭头函数

注:箭头函数不改变this指代

class Animal {constructor() {this.type = 'animal';}says(say) {setTimeout(() => {console.log(this.type + ' says ' + say);}, 1000);}
}
var animal = new Animal();
animal.says('hello');
//输出结果:animal says hello

下面咱们简单了解一下什么是bind()方法和箭头函数!

原文链接:https://editor.csdn.net/md/?articleId=105790363

bind()

bind()方法,顾名思义,就是绑定的意思

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,即从第二个参数起,会依次传递给原始函数

例如:fn.bind(obj),言外之意就是 obj.fn(),fn函数体内的this自然就指向obj

语法:fn.bind(this,arg1,arg2,…);

小例子:

var a = {b:function(){var fn = function(){console.log(this.c+' '+'world');};fn();},c:'hello'
}
a.b();
// undefined world
//注:这里的this指代的是全局作用域,所以返回undefined
bind()绑定一
var a = {b:function(){var fn = function(){console.log(this.c+' '+'world');}.bind(this);fn();},c:'hello'
}
a.b();
// hello world
//注:因为该函数是一个对象的方法,则它的this指针指向这个对象
bind()绑定二
var a = {b:function(){var fn = function(){console.log(this.c+' '+'world');};fn.bind(this)();},c:'hello'
}
a.b();
// hello world
bind()传入多个参数
function fn(y,z){return this.x+y+z;
}
var obj = {x:2
};
var num = fn.bind(obj,3,5);
console.log(num()); //10
//注:bind方法会把它的第一个实参绑定给fn函数体内的this,所以这里的this即指向obj对象
//从第二个参数起,会依次传递给原始函数,即y=3,z=5

箭头函数

箭头函数是ES6新出来的写法,它的语法比函数表达式更简洁,并且没有自己的this、arguments、super或new.target

箭头函数不需要 function 关键字来创建函数,省略 return 关键字,继承当前上下文的 this 关键字

箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数

箭头函数小细节:

1.如果参数只有一个,可以省略()
/*匿名函数*/
let fn1 = function(a){return a*a;
}
console.log(fn1(5));//25/*箭头函数*/
let fn2 = n =>{return n*n;
}
console.log(fn2(5));//25
//注:虽然可以省略return,但为了方便阅读,建议保留return
2.如果return只有一条语句,可以省略{}
let fn = (a,b) => a + b;
console.log(fn(8,9));//17
3.不改变上下文的this指代
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><div id="box1">按钮1</div><div id="box2">按钮2</div><script>let oBox1 = document.querySelector('#box1');let oBox2 = document.querySelector('#box2');console.log(this); //window//匿名函数oBox1.onclick = function(){console.log(this);//输出:<div id="box1">按钮1</div> //this指代的是oBox1}//箭头函数:不改变上下文的this指代oBox2.onclick = () =>{console.log(this); //window}</script></body>
</html>

注:箭头函数没有单独的this
如果是该函数是一个构造函数,this指针指向一个新的对象
在严格模式下的函数调用下,this指向undefined
如果是该函数是一个对象的方法,则它的this指针指向这个对象

原文链接:https://editor.csdn.net/md/?articleId=105790363

关于bind()和箭头函数就简单介绍到这里,想深入了解还需要查看官方文档!

学到很多东西的诀窍,就是一下子不要学很多 ——洛克

解决this指代的三种常用方法相关推荐

  1. 【H5】解决ios禁止缩放失效的方法

    [H5]解决ios禁止缩放失效的方法 参考文章: (1)[H5]解决ios禁止缩放失效的方法 (2)https://www.cnblogs.com/gentle-Lee/p/12154924.html ...

  2. 前端——解决微信网页清除缓存的方法

    前端--解决微信网页清除缓存的方法 参考文章: (1)前端--解决微信网页清除缓存的方法 (2)https://www.cnblogs.com/fkcqwq/p/9604184.html 备忘一下.

  3. CSS - 解决placeholder不起作用的方法

    CSS - 解决placeholder不起作用的方法 参考文章: (1)CSS - 解决placeholder不起作用的方法 (2)https://www.cnblogs.com/500m/p/115 ...

  4. Eclipse解决Ctrl+c很卡的方法

    Eclipse解决Ctrl+c很卡的方法 参考文章: (1)Eclipse解决Ctrl+c很卡的方法 (2)https://www.cnblogs.com/9421/p/6220194.html 备忘 ...

  5. 解决多线程安全问题-无非两个方法synchronized和lock 具体原理以及如何 获取锁AQS算法 (百度-美团)

    解决多线程安全问题-无非两个方法synchronized和lock 具体原理以及如何 获取锁AQS算法 (百度-美团) 参考文章: (1)解决多线程安全问题-无非两个方法synchronized和lo ...

  6. vue开发环境和生产环境里面解决跨域的几种方法

    vue开发环境和生产环境里面解决跨域的几种方法 参考文章: (1)vue开发环境和生产环境里面解决跨域的几种方法 (2)https://www.cnblogs.com/pass245939319/p/ ...

  7. Ubuntu 11.04解决txt文档中文乱码方法

    Ubuntu 11.04解决txt文档中文乱码方法: $ gconftool-2 --set --type=list --list-type=string /apps/gedit-2/preferen ...

  8. 最新解决ora-01034:oracle not available 的方法

    最新解决ora-01034:oracle not available 的方法 今天配置oracle10g时遇到ORACLE出现下面提示时: ora-01034:oracle   not   avail ...

  9. java常见的ide_在三个Java IDE中生成的三种常见方法

    java常见的ide 在本文中,我研究了NetBeans 8.0.2 , IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种"通用"方法[ e ...

最新文章

  1. razor html帮助器,在 ASP.NET 网页(Razor)网站中创建和使用帮助器 | Microsoft Docs
  2. squid命中率分析参数注释
  3. 一步步实现 Redis 搜索引擎
  4. centos 8 卸载anaconda_Centos7安装JDK1.8
  5. python什么时候要缩进_不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)...
  6. Matplotlib实例教程(九)热力图
  7. ajax+php跨域请求数据库,基于jQuery的ajax跨域请求,PHP作为服务器端代码
  8. php limit限流,php+redis 限流
  9. C#读书笔记:线程,任务和同步
  10. 评论:Arun Gupta撰写的“ Java EE 6 Pocket Guide”
  11. 如何避免单元测试陷阱?
  12. Vue异步获取数据后初始化数据不能及时更新
  13. wifi数据包解析_详细解析WiFi模块的基础知识
  14. php 自定义模板标签,自定义模板解析list标签
  15. 51单片机dds信号发生器 扫频 c语言,基于DDS正弦信号发生器设计.doc
  16. nginx搭建html
  17. 【计算机网络】PPP和PPPoE协议
  18. Qt 快速入门学习笔记
  19. 初入测试如何编写测试用例?从3个方面带你写一个合格的测试用例
  20. APP批量自动生成各种不同分辨率尺寸图标和启动页(Android和iOS都支持) - 使用cordova-res图文教程

热门文章

  1. 图解项目管理全流程图及详细管理过程
  2. Word 2007 文本粘贴快捷键及无法输入西文引号在方框里打勾等问题
  3. 十款优质企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)
  4. 微博至 bilibili 视频搬运脚本
  5. HBASE 2.0 hbck使用
  6. Vuetify下载图片的问题探究
  7. ch06-Pytorch的正则化与归一化
  8. python中 的意思_Python中 * ** 的意思及使用与区别
  9. Redis在实际开发中的运用场景
  10. 分类问题的评价指标:多标签分类【基于标签度量(同多分类一样):准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1】【基于样本度量:Hamming Loss...】