资讯专栏INFORMATION COLUMN

用最简单的方法判断JavaScript中this的指向

gggggggbong / 328人阅读

摘要:法则一对象方法中的指向对象本身箭头函数形式的除外法则二多层嵌套函数中的指向等同于包含该的最近一个的箭头函数没有独立的作用域,所以继续往外层走,走到了。

目录
* 一个特例
* 开始判断
    * 法则一:对象方法中的this指向对象本身(箭头函数形式的除外)
    * 法则二:多层嵌套函数中的this指向等同于包含该this的最近一个function的this
    * 法则三:箭头函数以及非指向对象方法中的function的情况下this指向window
* 习题集
    * 普通函数中的this
    * 函数执行后返回另外一个函数中的this(普通函数中)
    * 多层嵌套函数中的this(定时器&箭头函数)1
    * 多层嵌套函数中的this(定时器&箭头函数)2
一个特例

在正式开始之前,我们先来说一个特例。

// 构造函数
function Student(name) {
  this.name = name
}
// 创建小明和小红两个实例
var XM = new Student("xiaoming")
var XH = new Student("xiaohong")
// 输出信息
console.log(XM)  // Student {name: "xiaoming"}
console.log(XH)  // Student {name: "xiaohong"}

在构造函数中,this上的值会在创建实例的时候被绑定到新创建的实例上。不适用于下面的判断方法,所以特此说明。

开始判断

下面是一个典型例子,我们的分析从这里开始。

var x = {
  name: "bw2",
  getName1: function() {
    console.log(this)
  },
  getName2: function() {
    setTimeout(() => {
      console.log(this)
    },0)
  },
  getName31: () => {
    console.log(this)
  },
  getName32: function() {
    return function() {
      console.log(this)
    }
  }
}
x.getName1()  // {name: "bw2", getName1: ƒ}
x.getName2()  // {name: "bw2", getName1: ƒ}
x.getName31()  // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
x.getName32()()  // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
法则一:对象方法中的this指向对象本身(箭头函数形式的除外)
var x = {
  name: "bw2",
  getName1: function() {
    console.log(this)
  }
}
x.getName1()  // {name: "bw2", getName1: ƒ}
法则二:多层嵌套函数中的this指向等同于包含该this的最近一个function的this

箭头函数没有独立的this作用域,所以继续往外层走,走到了getName: function(){}。那么就是他了,this指向等同于这个function内部的this指向。根据法则一,this指向对象本身。

var x = {
  name: "bw2",
  getName2: function() {
    console.log(this)  // 等同于此处的this
    setTimeout(() => {
      console.log(this)  // 原始的this位置
    },0)
  }
}
x.getName2()  // {name: "bw2", getName1: ƒ}

我们可以试着在浏览器中运行,看看结果。

法则三:箭头函数以及非指向对象方法中的function的情况下this指向window

根据法则二,this是指向最近的function,因此,这里的this等同于返回的函数中的this,不是对象方法中的this,所以,指向全局。

是不是感觉有点奇怪?不过实践证明确实如此。

var x = {
  name: "bw2",
  getName31: () => {
    console.log(this)
  },
  getName32: function() {
    return function() {
      console.log(this)
    }
  }
}
x.getName31()  // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
x.getName32()()  // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
习题集

欢迎大家按照法则一到三依次判断,猜测结果,并在浏览器下测试。测试结果也可以回复,大家一起讨论。

因本人能力有限,该系列法则可能在部分情况下失效。欢迎大家一起讨论。

下面是做题时间。

普通函数中的this
function x() {
  console.log(this)
}
x()
函数执行后返回另外一个函数中的this(普通函数中)
function xx(){
  return function() {
    console.log(this)
  }
}
xx()()
多层嵌套函数中的this(定时器&箭头函数)1
var x = {
  name: "bw2",
  getName: () => {
    setTimeout(() => {
      console.log(this)
    },0)
  }
}
x.getName()
多层嵌套函数中的this(定时器&箭头函数)2
var x = {
  name: "bw2",
  getName: () => {
    setTimeout(function() {
      console.log(this)
    },0)
  }
}
x.getName()

再次说明,该法则为实验性法则,未进行大范围的测试,不保证在所有情况下都有一致的结果。如果你发现了法则判断失败的情况,欢迎留言,一起探讨。

欢迎关注前端进阶指南微信公众号:

另外我也创了一个对应的QQ群:660112451,欢迎一起交流。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85223.html

相关文章

  • 用最简单方式聊一下JavaScript观察者模式

    摘要:观察者模式,是设计模式之一。即便如此,笔者仍精心准备了这篇博客,期望用最简单的方式来介绍下该模式。这里有个小知识点提一下函数对象的属性就是该函数名最后是思路是通过找到指定数组,然后对数组中的回调函数进行依次调用,达到发布的目的。 观察者模式,是JavaScript设计模式之一。当然也不仅仅限于JavaScript这门语言,网上对该模式的介绍已是多如牛毛,而且讲得各有特色各有心得。即便如...

    megatron 评论0 收藏0
  • javascript继承你了解多少?

    摘要:和构造函数前面提到,是个内置隐藏属性,虽然在可以通过访问,但是其设计本意是不可被读取和修改的,那么我们如何利用原型链来建立继承关系提供了关键字。到这儿,思路就清晰了,怎么让对象和对象的相连实现继承只需把的构造函数的连接到就行了。 什么是继承? 大多数人使用继承不外乎是为了获得这两点好处,代码的抽象和代码的复用。代码的抽象就不用说了,交通工具和汽车这类的例子数不胜数,在传统的OO语言中(...

    baishancloud 评论0 收藏0
  • js温故而知新7(面向对象编程)——学习廖雪峰js教程

    摘要:不区分类和实例的概念,而是通过原型来实现面向对象编程。新创建的的原型链是也就是说,的原型指向函数的原型。最后,创建一个对象代码和前面章节完全一样小明继承用定义对象的另一个巨大的好处是继承更方便了。 JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。 原型是指当我们想要创建xiaoming这个具体的学生时,我们并没有一个Student类型可用...

    Jaden 评论0 收藏0
  • JavaScript EventEmitter

    摘要:事件删除可有可无。创建了一个类,然后在构造函数里初始化一个类的属性,这个属性不需要要继承任何东西,所以用了。但这不是必要的,因为实例化一个都会调用构造函数,皆为初始状态,应该是不可能已经定义了的,可去掉。成功执行结束后返回。 GitHub地址:JavaScript EventEmitter博客地址:JavaScript EventEmitter 水平有限,欢迎批评指正 2个多月前把 ...

    lovXin 评论0 收藏0
  • 这两天老是有兄弟问到Vue登陆和注册,登陆成功留在首页,没有登录回到登录页面,现在我用最简单实用

    摘要:其实登录注册,并且登录一次保持登录的状态,是每个项目都需要实现的功能。 其实登录注册,并且登录一次保持登录的状态,是每个项目都需要实现的功能。 网上也有很多的方法,不过,不是通俗易懂,在这里说一下我自己的方法,非常简单实用核心就是用localStorage存、取数据,这样当刷新浏览器,或者关闭在打开的时候能达到预期想要的效果 在router/index.js中 import Vue ...

    gplane 评论0 收藏0

发表评论

0条评论

gggggggbong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<