资讯专栏INFORMATION COLUMN

this 的工作原理

Salamander / 266人阅读

摘要:的工作原理有一套完全不同于其它语言的对的处理机制。全局范围内当在全部范围内使用,它将会指向全局对象。因此中的不会指向,因为只可能出现在上述的五种情况中。虽然的晚绑定特性似乎并不友好,但是这确实基于原型继承赖以生存的土壤。

this 的工作原理

JavaScript 有一套完全不同于其它语言的对 this 的处理机制。
种不同的情况下 ,this 指向的各不相同。

全局范围内
this;

当在全部范围内使用 this,它将会指向全局对象。

  

译者注:浏览器中运行的 JavaScript 脚本,这个全局对象是 window

函数调用
foo();

这里 this 也会指向全局对象。

  

ES5 注意: 在严格模式下(strict mode),不存在全局变量。
这种情况下 this 将会是 undefined

方法调用
test.foo(); 

这个例子中,this 指向 test 对象。

调用构造函数
new foo(); 

如果函数倾向于和 new 关键词一块使用,则我们称这个函数是 构造函数。
在函数内部,this 指向新创建的对象。

显式的设置 this
function foo(a, b, c) {}

var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示
foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3

当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被
显式设置为函数调用的第一个参数。

因此函数调用的规则在上例中已经不适用了,在foo 函数内 this 被设置成了 bar

  

注意: 在对象的字面声明语法中,this 不能用来指向对象本身。
因此 var obj = {me: this} 中的 me 不会指向 obj,因为 this 只可能出现在上述的五种情况中。
译者注:这个例子中,如果是在浏览器中运行,obj.me 等于 window 对象。

常见误解

尽管大部分的情况都说的过去,不过第一个规则(译者注:这里指的应该是第二个规则,也就是直接调用函数时,this 指向全局对象)
被认为是JavaScript语言另一个错误设计的地方,因为它从来就没有实际的用途。

Foo.method = function() {
    function test() {
        // this 将会被设置为全局对象(译者注:浏览器环境中也就是 window 对象)
    }
    test();
}

一个常见的误解是 test 中的 this 将会指向 Foo 对象,实际上不是这样子的。

为了在 test 中获取对 Foo 对象的引用,我们需要在 method 函数内部创建一个局部变量指向 Foo 对象。

Foo.method = function() {
    var that = this;
    function test() {
        // 使用 that 来指向 Foo 对象
    }
    test();
}

that 只是我们随意起的名字,不过这个名字被广泛的用来指向外部的 this 对象。
在 闭包 一节,我们可以看到 that 可以作为参数传递。

方法的赋值表达式

另一个看起来奇怪的地方是函数别名,也就是将一个方法赋值给一个变量。

var test = someObject.methodTest;
test();

上例中,test 就像一个普通的函数被调用;因此,函数内的 this 将不再被指向到 someObject 对象。

虽然 this 的晚绑定特性似乎并不友好,但是这确实基于原型继承赖以生存的土壤。

function Foo() {}
Foo.prototype.method = function() {};

function Bar() {}
Bar.prototype = Foo.prototype;

new Bar().method();

method 被调用时,this 将会指向 Bar 的实例对象。

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

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

相关文章

  • 深入浅出,JS原型链工作原理

    摘要:前言原型链,即原型链条。原型的作用在中,每个对象都有自己的原型。访问的属性方法依旧不存在于该原型,则会继续访问该原型的原型 前言:原型链,即原型链条。它是由原型、原型的原型、原型的原型的原型...这一规则组合成的,经常被应用于继承。 原型的作用在JS中,每个对象都有自己的原型。当我们访问对象的属性和方法时,JS会先访问对象本身的属性和方法。如果对象本身不包含这些属性和方法,则访问对象...

    Ali_ 评论0 收藏0
  • JavaScript是如何工作:深入类和继承内部原理+Babel和 TypeScript 之间转换

    摘要:下面是用实现转成抽象语法树如下还支持继承以下是转换结果最终的结果还是代码,其中包含库中的一些函数。可以使用新的易于使用的类定义,但是它仍然会创建构造函数和分配原型。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 15 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是...

    PrototypeZ 评论0 收藏0
  • 【译】this 是什么?JavaScript 对象内部工作原理

    摘要:关键字会实例化一个新的对象实例,并在执行构造函数时将指向该实例。原文链接译是什么对象的内部工作原理 原文链接:What is this? The Inner Workings of JavaScript Objects (需要梯子) 原文作者:Eric Elliott 译文永久链接:【译】什么是 this?JavaScript 对象的内部工作原理 译者:士心 翻译目的:函数动...

    Hwg 评论0 收藏0
  • 原理剖析(第 003 篇)ThreadPoolExecutor工作原理分析

    摘要:原理剖析第篇工作原理分析一大致介绍相信大家都用过线程池,对该类应该一点都不陌生了我们之所以要用到线程池,线程池主要用来解决线程生命周期开销问题和资源不足问题我们通过对多个任务重用线程以及控制线程池的数目可以有效防止资源不足的情况本章节就着 原理剖析(第 003 篇)ThreadPoolExecutor工作原理分析 - 一、大致介绍 1、相信大家都用过线程池,对该类ThreadPoolE...

    CatalpaFlat 评论0 收藏0
  • 原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上)

    摘要:端引导类线程管理组线程管理组将设置到服务端引导类中指定通道类型为,一种异步模式,阻塞模式为设置让服务器监听某个端口已等待客户端连接。 原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上) - 一、大致介绍 1、Netty这个词,对于熟悉并发的童鞋一点都不陌生,它是一个异步事件驱动型的网络通信框架; 2、使用Netty不需要我们关注过多NIO的API操作,简简单单的使用即可...

    coordinate35 评论0 收藏0

发表评论

0条评论

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