博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript中的this
阅读量:6257 次
发布时间:2019-06-22

本文共 2780 字,大约阅读时间需要 9 分钟。

定义

简单的说this就是属性或方法运行时,当前所在的对象。和运行时所处的环境相关,而与编写代码时所在位置无关(ES5)。

  • 常规操作(1)
//最常见的用法var A = {  name: '张三',  describe: function () {    return '姓名:'+ this.name;  }};复制代码

this属于方法describe,而方法describe又属于对A,所以this是指向的对象A,在这个时候this.name等同于a.name

  • 常规操作(2)
function f() {  return '姓名:'+ this.name;}var A = {  name: '张三',  describe: f};var B = {  name: '李四',  describe: f};var C = {  name: '赵六',  describe: function{    return '姓名:'+ this.name;    }};var name='王五'var f2=C.describeA.describe() // "姓名:张三"B.describe() // "姓名:李四"f()          // "姓名:王五"f2()         //"姓名: 赵六"复制代码

由于this指向是根据环境变化的,所以A.describe()方法B.describe()输出的结果会不同,因为f方法的所在的对象变了。所以this指向改变了(注意: nodejs和浏览器环境下,this所指向的全局对象不一样,所以输出结果会不同。nodejs中f() 输出的为undefined,话说这个坑困扰了我很久!!

常见的坑

由于this只针对的指向不明确,所以会经常有各种坑。下面来列举一下几个常见的:

  • 函数自执行的时候,this指向的事全局对象Window。先看一个复杂点的例子:
var o = {  f1: function () {    console.log(this);    var f2 = function () {      console.log(this);    }();  }}o.f1()// Object (f1中输出的事对象o)// Window (f2中输出的是全局对象Window)复制代码

上述情况中this的指向,与我们想要的结果明显不符,上述代码实际执行的为:

var temp = function () {  console.log(this);};var o = {  f1: function () {    console.log(this);    var f2 = temp();  }}复制代码

函数自执行的定义:函数名+()的调用方式叫做自执行。 上面的temp()就是函数名加括号的调用方式,所以是自执行

var f2 = function () {      console.log(this);    }();        //上述代码实际上可以转换为:      var f2 = function () {      console.log(this);    };    f2();       //自执行复制代码

那么问题来了,为什么上述的o.f1()的时候,f1中的this指向的是对象o而不是全局对象window呢?

答案在于方法和函数的区别,o.f1()表示的是调用的对象o中的方法,而f2()则表示的是调用函数f2(),它们最大的区别,就是有没有通过对象来调用。

知道区别了,接下来看看其他例子:

function fn(){     	console.log(this); //Window   }    fn(); //最常见的自执行,函数加括号。以前只知道是指向全局,现在知道为什么了    复制代码

ES6箭头函数中的this

箭头函数是ES6中新增的一种简洁的函数书写方式,基本语法是:参数 => 函数体。 之所以把箭头函数单独拿出来说,是因为箭头函数与我们常见的函数,有很多不同之处,this的指向就是区别之一。

箭头函数this的定义:箭头函数的中没有this,所以箭头函数中的this是直接继承(或者说调用)父级的this,并且箭头函数的this是在定义时绑定,所以和运行环境无关,这点和普通函数相反。

  • 箭头函数this的例子:
var x = 11;   var obj = {   x: 22,   say: () => {   console.log(this.x);   },   say2: function () {   console.log(this.x);   }   }   obj.say();      //输出11   obj.say2();     //输出22   //1.因为继承的是父级的this,而父级的this指向的是全局,所以say()拿到的数据是11//2.第二个普通方法,所以拿到的是x=22复制代码

setTimeout的this

先举个常见的栗子:

var Person = {    'age': 18,    'sayHello': function () {        setTimeout(function () {        console.log(this.age);        });    }};var age = 20;Person.sayHello();  // 20var Person1 = {    'age': 18,    'sayHello': function () {      setTimeout(()=>{        console.log(this.age);      });    }};var age = 20;Person1.sayHello();  // 18复制代码

Person1.sayHello();还比较好理解,因为使用了箭头函数,所以this继承自sayHello对象中this,而sayHello对象的this指向的是Person1对象。所以Person1.sayHello()中的this.age实际上是Person1.age。

那么为什么Person.sayHello()console.log(this.age)输出的是20呢? 答案是由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的this的值是不一样的。

转载地址:http://nxasa.baihongyu.com/

你可能感兴趣的文章
usdt的坑
查看>>
郑雨林-产业互联网
查看>>
OLGhostAlertView
查看>>
互联网常见系统缩写全称
查看>>
JSON.parse()和JSON.stringify()
查看>>
在springboot中打印mybatis-sql语句
查看>>
配置Git HTTPS 下记住密码
查看>>
java 判断当前时间符合cron时间表达式
查看>>
Python复数表示表示和计算
查看>>
Android 短信拦截&来去电话拦截
查看>>
Telnet协议的实现
查看>>
【脚本语言系列】关于MATLAB编程,你需要知道的事
查看>>
数人云|听说大神都在用这25种软件部署工具,你用过几种?
查看>>
vc+opengl编程unresolved external symbol 报错处理
查看>>
SpringMVC的工作原理
查看>>
python
查看>>
jquery插件 jsp+servlet+uploadify3.1 文件上传
查看>>
flex + spring 报 Error #2032
查看>>
区别 i++ ,++i
查看>>
scala常用技巧
查看>>