博客
关于我
js中this的指向问题
阅读量:674 次
发布时间:2019-03-16

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

this 指向在 JavaScript 中的行为分析

1. 窗口对象的概念

浏览器对象模型(Browser Object Modal,简称 BOM)是浏览器使用的内部对象模型。在大多数浏览器环境中,窗口对象(window对象)是最基层的抽象。每一个浏览器窗口都会有一个对应的 window 对象,而这个 window 对象会用于创建和管理其他对象,比如页面元素、框架以及所有其他浏览器内置的功能。

例如,打开一个新标签或窗口时,会自动生成一个 window 对象。我们通常可以访问 window 对象来执行全局操作。

示例:

var a = 1;console.log(a);  // 输出: 1console.log(window.a);  // 输出: 1

托管层:在这些代码中,变量 a 存在于全局作用域内,从而成为 window 对象的属性。


2. this 关键字的运行时绑定

this 关键字的指向基于函数调用的上下文环境决定,即运行时绑定。具体来说,this 指向:

function 调用方式 => this 指向的对象----------------------- ----------普通函数调用          window对象对象方法调用          目标对象构造函数调用          newly 创建的对象

2.1 函数调用的类型

不同的函数调用方式会影响 this 的指向。

2.1.1: 函数作为普通函数调用

function func() {    console.log(this.a);}func();console.log(window.a);

输出: undefined

原因:this 指向 window 对象,而 a 未被定义。

此时,如果全局定义了 a

var a = 5;func();

输出将变为:

输出: 5

原因:a 存在于 window 对象中。


2.1.2: 方法作为对象属性

function func() {}var obj = {    a: 42,    func: func};obj.func();

输出: 42

原因:方法调用时 this 指向 obj。

在这种情况下,仅仅赋值函数不会影响 this 的指向。只有在调用对象方法时,this 才会指向该对象。


2.1.3: 构造函数调用

function Test() {    this.x = 1;    console.log(this.x);}var obj = new Test();

输出: 1

原因:构造函数会使用 new 关键字,this 指向新创建的实例。


2.2 事件绑定的三种方式

在 JavaScript 中,可以用三种方式绑定事件处理函数:

2.2.1: 使用 HTML onclick 属性

        

加载结果:

第一个按钮调用时 this 指向 window,因为宿主 Web 浏览器在如果使用现有 onclick 属性,会自动绑定到 window 对象。第二个按钮也会绑定到 window(因为直接调用 window.typeOne())。


2.2.2: 通过动态绑定

button元素的 id 为 "two"
document.getElementById('two').addEventListener('click', function() {    console.log('DOM对象', this);});

输出: DOM 元素

原因:this 指向发送事件的 DOM 元素。


2.2.3: 使用 setTimeout

function func() {    console.log('定时器中的 this:", this.a');}var obj = {a: 42};setTimeout(func, 1000);

输出: undefined

原因:setTimeout 调用的上下文环境是全局环境,this 指向 window。如果需要保持 this 指向对象,可以使用函数中的 this 分别进行绑定。


3. 特殊情况中的 this 指向

3.1 函数作为 DOM 事件监听器

var obj = {    a: 42,    func: function() {        console.log('this 是:', this);    }};obj.func();  // this 指向 obj

3.2 定时器中的函数调用

默认情况下,timeout 中的函数会认为 this 指向 window 对象,除非使用正确的绑定方法。

例如:

setTimeout(function() {    console.log('定时器执行时', this);}, 1000);

输出: window 对象


3.3 箭头函数中的 this 指向

var color = 'red';var o = {    color: 'blue',    sayColor: () => {        console.log('箭头函数', this.color);    }};o.sayColor();

输出: blue

原因:箭头函数不会改变 this 的指向,this 继承自 o 对象。

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

你可能感兴趣的文章
org.apache.ibatis.exceptions.PersistenceException:
查看>>
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned
查看>>
org.apache.ibatis.type.TypeException: Could not resolve type alias 'xxxx'异常
查看>>
org.apache.poi.hssf.util.Region
查看>>
org.apache.xmlbeans.XmlOptions.setEntityExpansionLimit(I)Lorg/apache/xmlbeans/XmlOptions;
查看>>
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /
查看>>
org.hibernate.HibernateException: Unable to get the default Bean Validation factory
查看>>
org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
查看>>
org.springframework.beans.factory.BeanDefinitionStoreException
查看>>
org.springframework.boot:spring boot maven plugin丢失---SpringCloud Alibaba_若依微服务框架改造_--工作笔记012
查看>>
SQL-CLR 类型映射 (LINQ to SQL)
查看>>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
查看>>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
查看>>
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded
查看>>
org.tinygroup.serviceprocessor-服务处理器
查看>>
org/eclipse/jetty/server/Connector : Unsupported major.minor version 52.0
查看>>
org/hibernate/validator/internal/engine
查看>>
Orleans框架------基于Actor模型生成分布式Id
查看>>
SQL-36 创建一个actor_name表,将actor表中的所有first_name以及last_name导入改表。
查看>>
ORM sqlachemy学习
查看>>