关于this

简介: 关于this

说明

《你不知道的JavaScript》学习笔记。



为什么要用this

书中举了一个例子:

function identify() {
    return this.name.toUpperCase();
}
function speak() {
    var greeting = "Hello, I'm " + identify.call( this );
    console.log( greeting );
}
var me = {
    name: "Kyle"
};
var you = {
    name: "Reader"
};
identify.call( me ); // KYLE
identify.call( you ); // READER
speak.call( me ); // Hello, 我是 KYLE
speak.call( you ); // Hello, 我是 READER


如果不使用 this,那就需要给 identify() 和 speak() 显式的传入一个上下文对象。

function identify(context) {
    return context.name.toUpperCase();
}
function speak(context) {
    var greeting = "Hello, I'm " + identify( context );
    console.log( greeting );
}
var me = {
    name: "Kyle"
};
var you = {
    name: "Reader"
};
identify( you ); // READER
speak( me ); //hello, 我是 KYLE


随着使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用 this 则不会这样。

this 提供了一种更优雅的方式来隐式“传递” 一个对象引用, 因此可以将 API 设计得更加简洁并且易于复用。



误解


两种常见的对于 this 的错误解释。


1、指向自身

1、先看一个例子:想要记录一下函数 foo 被调用的次数。

function foo(num) {
    console.log( "foo: " + num );
    // 记录 foo 被调用的次数
    this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// foo 被调用了多少次?
console.log( foo.count ); // 0
console.log( count ); // NaN


显然 foo() 里的 this 不是指向那个函数对象,虽然属性名相同,跟对象却不相同。


2、再看下面两个函数

function foo() {
    foo.count = 4; // foo 指向它自身
}
setTimeout( function(){
    // 匿名(没有名字的) 函数无法指向自身
}, 10 );


代码分析:

   1、foo() 函数是具名函数,在它的内部可以使用 foo 来引用自身

   2、传入 setTimeout() 的回调函数是匿名函数,无法从函数内部引用自身


3、解决方法


   1、使用 foo 标识符替代 this 来引用函数对象

   2、强制 this 指向 foo 函数对象


方法1:

function foo(num) {
    console.log( "foo: " + num );
    // 记录 foo 被调用的次数
    foo.count++;
}


方法2:

var i;
for (i=0; i<10; i++) {
if (i > 5) {
    // 使用 call(..) 可以确保 this 指向函数对象 foo 本身
    foo.call( foo, i );
}
}




2、它的作用域


  • this 在任何情况下都不指向函数的词法作用域。
  • 在 JavaScript 内部, 作用域确实和对象类似, 可见的标识符都是它的属性。
  • 作用域“对象” 无法通过 JavaScript 代码访问, 它存在于 JavaScript 引擎内部。




this到底是什么

当一个函数被调用时, 会创建一个活动记录(有时候也称为执行上下文)。 这个记录会包含函数在哪里被调用(调用栈)、 函数的调用方法、 传入的参数等信息。 this 就是记录的其中一个属性, 会在函数执行的过程中用到。


  • this 是在运行时进行绑定的, 并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。
  • this 的绑定和函数声明的位置没有任何关系, 只取决于函数的调用方式。
目录
相关文章
|
3天前
|
人工智能 弹性计算 API
创意“孵化机”——基于通义万相加速绘画创作流程
阿里云在2023年推出了AI绘画平台**通义万相**,该平台能够根据文本描述生成图像,应用于艺术创作。近期,阿里云优化了通义万相的接入方式,提供API文档和一键部署服务,使得非技术人员也能轻松集成到Web应用中。为促进用户尝试,阿里云还推出了解决方案评测活动,参与者有机会获得奖品。通义万相通过ECS、OSS、VPC和DashScope等云服务支持,简化了技术架构,加速了绘画创作流程。此外,阿里云提供了优惠购买方案,新人享有特别折扣。该服务不仅适用于艺术家,还可应用于多个领域,提高内容生成效率。
70621 10
|
11天前
|
弹性计算 运维 网络安全
上云“加速器”——基于云效流水线快速上线企业门户网站
阿里云提出使用云效将项目代码部署到ECS,快速构建企业门户网站。该方案融合云原生技术和持续交付,通过云效流水线简化从开发到部署的全过程,实现快速迭代。文章详细阐述了技术架构,包括客户端、云解析DNS、VPC、ECS等组件,以及部署流程,包括准备阶段、部署网站服务、解析域名和可选的静态资源加速。此外,还介绍了如何使用云效平台创建流水线,实现自动化构建与部署,以及如何通过一键部署简化流程。整个方案旨在降低运维成本,提高速度和灵活性,同时提供域名备案和SSL证书配置的指导。
194558 73
上云“加速器”——基于云效流水线快速上线企业门户网站
|
11天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!
|
11天前
|
机器学习/深度学习 算法 开发工具
通义千问2(Qwen2)大语言模型在PAI-QuickStart的微调、评测与部署实践
阿里云的人工智能平台PAI,作为一站式的机器学习和深度学习平台,对Qwen2模型系列提供了全面的技术支持。无论是开发者还是企业客户,都可以通过PAI-QuickStart轻松实现Qwen2系列模型的微调、评测和快速部署。
|
13天前
|
人工智能 机器人 API
用AppFlow玩转通义百炼大模型应用
阿里云百炼平台提供一站式大模型开发服务,支持创建和定制应用,预置丰富插件和API。用户可以通过平台快速构建大模型应用,并利用AppFlow将其接入钉钉群聊,以AI卡片形式展示。
72874 3
|
11天前
|
存储 网络协议 安全
阿里云hpc8ae实例商业化发布详解
近日,全球领先的云计算厂商阿里云宣布最新HPC优化实例hpc8ae的正式商业化,该实例依托阿里云自研的「飞天+CIPU」架构体系,搭载第四代AMD EPYC处理器,专为高性能计算应用优化,特别适用于计算流体、有限元分析、多物理场模拟等仿真类应用,CAE场景下的性价比最少提升50%。
|
12天前
|
SQL 搜索推荐 OLAP
Flink 流批一体场景应用及落地情况
本文由阿里云 Flink 团队苏轩楠老师撰写,旨在介绍 Flink 流批一体在几个常见场景下的应用。
67312 1
Flink 流批一体场景应用及落地情况
|
12天前
|
Kubernetes 测试技术 应用服务中间件
基于 Nginx Ingress + 云效 AppStack 实现灰度发布
本文将演示结合云效 AppStack,来看下如何在阿里云 ACK 集群上进行应用的 Ingress 灰度发布。
64503 16
|
12天前
|
SQL 数据采集 DataWorks
DataWorks重磅推出全新资源组2.0,实现低成本灵活付费和动态平滑扩缩容
DataWorks资源组2.0上线,提供低成本、动态扩缩容的数据计算资源服务。
53750 5
DataWorks重磅推出全新资源组2.0,实现低成本灵活付费和动态平滑扩缩容
|
13天前
|
机器学习/深度学习 Kubernetes 算法框架/工具
容器服务 ACK 大模型推理最佳实践系列一:TensorRT-LLM
在 ACK 中使用 KServe 部署 Triton+TensorRT-LLM