全面解析this

全面解析this

this是一个很特别的关键字,也是Javascript中最复杂的机制之一,它被自动定义在所有函数的作用域中。如果你想要熟练的去使用他,那么你将需要了解一下几个问题。

1.为什么要用this

下面我们来解释一下为什么要使用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
复制代码

这段代码可以在不同的上下文对象(meyou)中重复使用函数identify()speak(),不用针对每个对象编写不同版本的函数。

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

function identify(context) {
    return context.name.toUpperCase();
}

function speak(context) {
    var greeting = "Hello, I'm " + identify( context );
    console.log( greeting );
}

identify( you ); // READER
speak(me); //Hello, 我是KYLE
复制代码

当然,使用显示可以使代码看起来更直观,但是随着你的使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用this则不会这样。

2.它的作用域

this指向函数的作用域。这个问题有点复杂,因为在某种情况下它是正确的,但是在其他情况下它却是错误的。 需要明确的是,this在任何情况下都不指向函数的词法作用域。在JavaScript内部,作用域确实和对象类似,可见的标识符都是它的属性。但是作用域“对象”无法通过JavaScript代码访问,它存在于JavaScript引擎内部。我们来观察一下下面的代码。

function foo() {
    var a = 2;
    this.bar();
}

function bar() {
    console.log( this.a );
}

foo(); // ReferenceError: a is not defined
复制代码

它试图(但是没有成功)跨越边界,使用this来隐式引用函数的词法作用域。

首先,这段代码试图通过this.bar()来引用bar()函数。这是绝对不可能成功的,调用bar()最自然的方法是省略前面的this,直接使用词法引用标识符。

此外,还试图使用this联通foo()bar()的词法作用域,从而让bar()可以访问foo()作用域里的变量a。这是不可能实现的,你不能使用this来引用一个词法作用域内部的东西。

每当你想要把this和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。

3.调用的位置

在理解this的绑定过程之前,首先要理解调用位置:调用位置就是函数在代码中被调用的位置(而不是声明的位置)

通常来说,寻找调用位置就是寻找“函数被调用的位置”,但是做起来并没有这么简单,因为某些编程模式可能会隐藏真正的调用位置。

最重要的是要分析调用栈(就是为了到达当前执行位置所调用的所有函数)。我们关心的调用位置就在当前正在执行的函数的前一个调用中。

下面我们来看看到底什么是调用栈和调用位置:

function baz() {
    // 当前调用栈是:baz
    // 因此,当前调用位置是全局作用域

    console.log( "baz" );
    bar(); // <-- bar的调用位置
}

function bar() {
    // 当前调用栈是baz -> bar
    // 因此,当前调用位置在baz中

    console.log( "bar" );
    foo(); // <-- foo的调用位置
}

function foo() {
    // 当前调用栈是baz -> bar -> foo
    // 因此,当前调用位置在bar中

    console.log( "foo" );
}

baz(); // <-- baz的调用位置
复制代码

注意我们是如何(从调用栈中)分析出真正的调用位置的,因为它决定了this的绑定。

4.绑定的规则

如果要判断一个运行中函数的this绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断this的绑定对象。

  • new调用?绑定到新创建的对象。
  • call或者apply(或者bind)调用?绑定到指定的对象。
  • 由上下文对象调用?绑定到那个上下文对象。
  • 默认:在严格模式下绑定到undefined,否则绑定到全局对象。
4.1 默认绑定

思考一下下面的代码:

function foo() { 
    console.log( this.a );
}

var a = 2;

foo(); // 2
复制代码

我们可以看到当调用foo()时,this.a被解析成了全局变量a。为什么?因为在本例中,函数调用时应用了this的默认绑定,因此this指向全局对象。

那么我们怎么知道这里应用了默认绑定呢?可以通过分析调用位置来看看foo()是如何调用的。在代码中,foo()是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则。

如果使用严格模式(strict mode),那么全局对象将无法使用默认绑定,因此this会绑定到undefined

function foo() { 
    "use strict";
     console.log( this.a ); 
}

var a = 2;

foo(); // TypeError: this is undefined
复制代码
4.2 上下文

第三方库的许多函数,以及JavaScript语言和宿主环境中许多新的内置函数,都提供了一个可选的参数,通常被称为“上下文”(context),其作用和bind(..)一样,确保你的回调函数使用指定的this

举例来说:

function foo(el) { 
    console.log( el, this.id );
}

var obj = {
    id: "awesome"
};

// 调用foo(..)时把this绑定到obj
[1, 2, 3].forEach( foo, obj );
// 1 awesome 2 awesome 3 awesome
复制代码

这些函数实际上就是通过call(..)或者apply(..)实现了显式绑定,这样你可以少些一些代码。

4.3 new绑定

思考下面的代码:

function foo(a) { 
    this.a = a;
} 

var bar = new foo(2);

console.log( bar.a ); // 2
复制代码

使用new来调用foo(..)时,我们会构造一个新对象并把它绑定到foo(..)调用中的this上。new是最后一种可以影响函数调用时this绑定行为的方法,我们称之为new绑定。

一定要注意,有些调用可能在无意中使用默认绑定规则。如果想“更安全”地忽略this绑定,你可以使用一个DMZ对象,比如ø = Object.create(null),以保护全局对象。

ES6中的箭头函数并不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定this,具体来说,箭头函数会继承外层函数调用的this绑定(无论this绑定到什么)。这其实和ES6之前代码中的self = this机制一样。

参考书:《你不知道的Javascript(上卷)》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介 出版日期: 2012年4月1日 《WCF全面解析(套装上下册)》由蒋金楠所著,是作者多年潜心研究WCF技术的心血之作,也是这些年来从事WCF开发的经验总结。书如其名,此书涵盖了WCF几乎所有的知识点,并对其底层框架进行了“庖丁解牛”式的剖析,力求将WCF的整个运行机制完整而清晰地呈现在读者面前。 《WCF全面解析(套装上下册)》上册的前四章在对WCF进行总体介绍的基础上,对构成终结点的三要素(地址、绑定和契约)进行了系统说明;随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章中采用WCF构建了一个具体的电子商务网站VM,它将指导你如何将理论应用于实践。 《WCF全面解析(套装上下册)》的下册主要涉及一些所谓的“高级”话题,主要包括如何在分布式环境中处理异常(第1章);元数据的导入与导出、发布与获取如何实现(第2章);如何利用WCF对事务的支持将分布式事务引入服务(第3章);如何利用并发与限流机制提高服务的吞吐量和可用性(第4章);如何利用可靠会话机制确保消息的“使命必达”(第5章);如何利用队列服务提供离线通信的支持(第6章);第7、8章主要涉及安全的相关内容,包括传输安全、授权与审核;第9章全景展示WCF服务端和客户端的运行时框架,以及在此基础上的所有扩展可能;最后一章为你带来WCF4.0几个独立的新特性。 编辑推荐 《WCF全面解析(套装上下册)》不仅适合尚未接触过WCF,希望尽快入门并进行深入研究的开发人员使用,同样也适合对WCF有一定了解的开发设计人员和架构师阅读。相信不同层次的读者都能从此书中找到自己希望了解的部分。 《WCF全面解析(套装上下册)》的内容不仅适合尚未接触过WCF,希望尽快入门并进行深入研究的开发人员,同样适合对WCF具有一定了解的开发设计人员和架构师。相信不同层次的读者都能从本书中找到自己希望了解的部分。阅读本书的读者需要对.NET,包括对C#和.NET Framework具有一定的了解。如果读者具备了DCOM、Enterprise Library Service、.NET Remoting、Web Service、MSMQ及SOA相关的基础,对阅读此书尽快掌握WCF将大有裨益。 名人推荐我经历了COM时代,一直把Don Box的《COMM本质论》奉为我的指路明灯。能把SOA机理和WCF这种特定厂商实现的技术讲得如《COM本质论》一样完美透彻的,那必属Artech这本经过自己深研、实践而著的心血结晶——《WCF全面解析》。如果你想成为SOA和WCF方面的专家,那么这本书就是你的最好法宝。想想你作为专家而获得的回报,那么你对这本书购买所付出的,简直是太值了。 ——《走出软件作坊》 作者 明源软件CTO 阿朱 首先,金楠是—位工作在一线的优秀的WCF技术人员,这符合我对阅读技术图书的第一个要求和期待。其次,金楠的写作文笔、专业责任也给人以充分信任,这在金楠的文字中读者可以体会。这本《WCF全面解析全面剖析了构建WCF应用所需要的各方面技术,剥丝抽茧,由浅入深,也是我非常欣赏的技术讲述方式。我相信《WCF全面解析》—书是搞WCF朋友的案头必备。 ——祝成科技与Boolan.com创始人.NET技术专家 李建忠 知识全面、论述准确、逻辑严密是本书的特点。这是一本各层次开发人员都可以从中受益的书:对于初、中级开发人员,它可以帮助你获得WCF全方位的知识,系统地梳理WCF的知识结构,提升动手实践能力;对于高级开发人员,它既可以有效弥补你WCF相关知识中的盲点,又可以让你在自己熟悉的知识点上领略作者的看法和理解。 ——资深架构师 曲春雨 作者简介蒋金楠,网名Artech,现就职于某知名软件公司担任高级软件顾问。连续5届微软MVP(最有价值专家),同时也是少数的双料MVP(Solutions Architecture+Connected System)之一。国内较早接触WCF的人之一,2007年2月起在个人博客(http://www.cnblogs.com/artech)上发表超过两百篇深入介绍WCF的文章,成为了目前国内WCF在线资料的主要来源。
《WCF全面解析(套装上下册)》由蒋金楠所著,是作者多年潜心研究WCF技术的心血之作,也是这些年来从事WCF开发的经验总结。书如其名,此书涵盖了WCF几乎所有的知识点,并对其底层框架进行了“庖丁解牛”式的剖析,力求将WCF的整个运行机制完整而清晰地呈现在读者面前。 《WCF全面解析(套装上下册)》上册的前四章在对WCF进行总体介绍的基础上,对构成终结点的三要素(地址、绑定和契约)进行了系统说明;随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章中采用WCF构建了一个具体的电子商务网站VM,它将指导你如何将理论应用于实践。 《WCF全面解析(套装上下册)》的下册主要涉及一些所谓的“高级”话题,主要包括如何在分布式环境中处理异常(第1章);元数据的导入与导出、发布与获取如何实现(第2章);如何利用WCF对事务的支持将分布式事务引入服务(第3章);如何利用并发与限流机制提高服务的吞吐量和可用性(第4章);如何利用可靠会话机制确保消息的“使命必达”(第5章);如何利用队列服务提供离线通信的支持(第6章);第7、8章主要涉及安全的相关内容,包括传输安全、授权与审核;第9章全景展示WCF服务端和客户端的运行时框架,以及在此基础上的所有扩展可能;最后一章为你带来WCF4.0几个独立的新特性。 编辑推荐 《WCF全面解析(套装上下册)》不仅适合尚未接触过WCF,希望尽快入门并进行深入研究的开发人员使用,同样也适合对WCF有一定了解的开发设计人员和架构师阅读。相信不同层次的读者都能从此书中找到自己希望了解的部分。 《WCF全面解析(套装上下册)》的内容不仅适合尚未接触过WCF,希望尽快入门并进行深入研究的开发人员,同样适合对WCF具有一定了解的开发设计人员和架构师。相信不同层次的读者都能从本书中找到自己希望了解的部分。阅读本书的读者需要对.NET,包括对C#和.NET Framework具有一定的了解。如果读者具备了DCOM、Enterprise Library Service、.NET Remoting、Web Service、MSMQ及SOA相关的基础,对阅读此书尽快掌握WCF将大有裨益。 名人推荐我经历了COM时代,一直把Don Box的《COMM本质论》奉为我的指路明灯。能把SOA机理和WCF这种特定厂商实现的技术讲得如《COM本质论》一样完美透彻的,那必属Artech这本经过自己深研、实践而著的心血结晶——《WCF全面解析》。如果你想成为SOA和WCF方面的专家,那么这本书就是你的最好法宝。想想你作为专家而获得的回报,那么你对这本书购买所付出的,简直是太值了。 ——《走出软件作坊》 作者 明源软件CTO 阿朱 首先,金楠是—位工作在一线的优秀的WCF技术人员,这符合我对阅读技术图书的第一个要求和期待。其次,金楠的写作文笔、专业责任也给人以充分信任,这在金楠的文字中读者可以体会。这本《WCF全面解析全面剖析了构建WCF应用所需要的各方面技术,剥丝抽茧,由浅入深,也是我非常欣赏的技术讲述方式。我相信《WCF全面解析》—书是搞WCF朋友的案头必备。 ——祝成科技与Boolan.com创始人.NET技术专家 李建忠 知识全面、论述准确、逻辑严密是本书的特点。这是一本各层次开发人员都可以从中受益的书:对于初、中级开发人员,它可以帮助你获得WCF全方位的知识,系统地梳理WCF的知识结构,提升动手实践能力;对于高级开发人员,它既可以有效弥补你WCF相关知识中的盲点,又可以让你在自己熟悉的知识点上领略作者的看法和理解。 ——资深架构师 曲春雨 作者简介蒋金楠,网名Artech,现就职于某知名软件公司担任高级软件顾问。连续5届微软MVP(最有价值专家),同时也是少数的双料MVP(Solutions Architecture+Connected System)之一。国内较早接触WCF的人之一,2007年2月起在个人博客(http://www.cnblogs.com/artech)上发表超过两百篇深入介绍WCF的文章,成为了目前国内WCF在线资料的主要来源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值