箭头函数 - 为什么会将全局对象打印到控制台? [复制]

2024-02-20

为什么o.foo()将全局对象打印到控制台?

let o = {
  foo: () => console.log(this),
  bar() { console.log(this); }
};

o.foo(); // Global object / undefined
o.bar(); // o

我认为箭头函数的等效项可能是这样的(但事实并非如此):

let o = {
    foo: function() {
        console.log(this);
    },
    bar() {   
        console.log(this);
    }
};

o.foo(); // o
o.bar(); // o

箭头功能retain the this of the 周围执行上下文 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-execution-contexts从它们被宣布时起。他们没有改变this一直如此,就像正常方法一样。

在您的示例中,周围没有执行上下文foo, so this is undefined。这与使用声明的函数具有相同的行为function关键字处于相同的范围并以相同的方式调用。您可以使用以下方法进行测试:

let foo = () => { return this; }
console.log(foo() === undefined);

From 2016 年 2 月 14 日的规范 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-function-definitions-runtime-semantics-evaluation:

ArrowFunction 中对参数、super 或 this 的任何引用都必须解析为词法封闭环境中的绑定。通常这将是直接封闭函数的函数环境.

(强调我的)

有趣的是,当该箭头函数出现在全局范围内时,BabelJS 转译器 https://babeljs.io/简单地输出

"use strict";

var foo = function foo() {
  return undefined;
};

好像这是唯一正确的行为。阅读规范,它似乎并不那么严格,但这似乎确实是正确的做法。

如果您设法使用不带模块的箭头运行 ES6 代码,那么您似乎最终可以得到这样的全局对象。每10.2.1 的规范 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-strict-mode-code:

  • 如果全局代码以包含使用严格指令的指令序言开头(请参阅 14.1.1),则全局代码是严格模式代码。
  • 模块代码始终是严格模式代码。

原来如此possible在非严格上下文中获取 ES6 代码。如果发生这种情况,那么this将使用经典后备并设置为window (in 规格为 9.2 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects作为一个未定义的[[ThisMode]]).

在这个例子中,没有立即封闭的函数,因此没有词法范围可供选择,所以this最终未定义。

在你的第二个例子中,捕获this没有什么区别:

let o = {
    foo: function() {
        var self = this;
        console.log(self);
    },
    bar() {
        
        console.log(this);
    }
};

The var self语句位于函数内,因此它不会执行任何操作。如果你要做:

let o = {
    foo: function() {
        var self = this;
        return function() {
            console.log(self);
        }
    }(),
    bar() {
        
        console.log(this);
    }
};

那么它将具有您期望的行为(大致),尽管this仍然是未定义的(或全局对象),因为你不在要捕获的词法环境中。

如果你要使用

class Foo {
  bar() {
    let baz = () => { return this; }
  }
}

then bar可以转译为

function bar() {
  var _this = this;

  var baz = function baz() {
    return _this;
  };
}

哪个做你做的事want。这只有在需要捕获周围环境的情况下才有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

箭头函数 - 为什么会将全局对象打印到控制台? [复制] 的相关文章

  • 如何在 Lambda 中将对象上传到 S3?

    似乎无法将对象上传到 Lambda 中的 S3 本地一切正常 日志中没有错误可以显示出了什么问题 代码如下 console log Loading function var AWS require aws sdk var s3 new AW
  • 为什么 Jshint 在此 if 语句中说“变量已定义”?

    我有这个代码 if something is true var someVar true else var someVar false JsHint 表示在 else 语句部分 someVar 已被定义 这是为什么 我该如何解决 Thank
  • Javascript“this”在 IE 中丢失上下文

    以下在 firefox safari chrome 中工作正常 在 IE 中 this 似乎在 handleEvent 函数中丢失上下文 警报的结果是 object Window 这不是我想要的 当从handleEvent 输出时 this
  • 获取 CRM 2011 中功能区按钮的 ID

    我创建了一个 JavaScript 我想在其中隐藏功能区Reactivate Lead按钮取决于某些条件 我通过在表单上按 F12 获得了按钮的 ID 即lead NoRelationship Form Mscrm Form lead Re
  • Javascript:使用 IIFE 和块语句之间的区别

    IIFE主要用于封装作用域 function let myVar 10 not global 但为什么不直接使用块语句呢 let myVar 10 also not global 除了范围封装之外 进一步使用 IIFE 是否还有其他好处 块
  • D3更新circle-pack数据新节点与现有节点重叠

    我正在关注一般更新模式 http bl ocks org mbostock 3808234但在分层方面存在问题 使用圆形包装布局 我pack新数据 update enter and exit圆形元素 然而 当新元素enter 它们重叠upd
  • 如何使传单圆圈标记可拖动?

    使用传单 我创建了一个L circleMarker我希望它是可拖动的 var marker L circleMarker new L LatLng 48 94603 2 25912 draggable true bindPopup Circ
  • CryptoJS 使用密码加密 AES,但 PHP 解密需要密钥

    我在用CryptoJS https code google com p crypto js AES加密字符串 function doHash msg msg String msg var passphrase aggourakia var
  • CSS 内边框?

    我纯粹用 CSS 创建了左侧的按钮 它是一个div 中的一个div 然而 右侧的三个按钮是background属性于img标签 我这样做是为了按照以下说明模拟翻转效果here http kyleschaeffer com best prac
  • html 图像 src 调用 javaScript 变量

    这是我的代码 我想问 我怎样才能做到这一点 img src img apple 我一直在尝试使用 call 函数和 document onload 但它根本不起作用 有人可以救我吗 我假设你只是想用 javascript 更新图像 src
  • 有没有办法在 React 中自动播放音频而不使用 onClick 事件?

    我在尝试在 componentDidMount 中播放音频时收到此错误 未捕获 承诺中 DOMException play 失败 因为用户没有先与文档交互 componentDidMount document getElementById
  • tomcat 7.0.50 java websocket 实现给出 404 错误

    我正在尝试使用 Java Websocket API 1 0 JSR 356 中指定的带注释端点在 tomcat 7 0 50 上实现 websocket 以下是我如何对其进行编码的简要步骤 1 使用 ServerEndpoint注解编写w
  • jslint 配置 |传递全局变量

    我如何提醒 jshint 我有全局变量 即命名它们 我知道你可以做到这一点 但我不记得语法了 我在这里定义了一个全局的 function window glob1 local var 稍后像这样使用 不同的 IIFE function gl
  • 纯 JS 相当于 Jquery eq()

    jquery 的纯等价物是什么eq 例如 我怎样才能实现 class1 class2 eq 0 text 1254 在纯 JavaScript 中 要获取数组中的元素索引 可以使用 在 JavaScript 中 因此 要重现您的代码 您可以
  • 只保留 A-Z 0-9 并使用 javascript 从字符串中删除其他字符

    我正在尝试验证字符串以使它们成为有效的网址 我只需要保留 A Z 0 9 并使用以下命令从字符串中删除其他字符javascript or jquery 例如 贝儿餐厅 我需要将其转换为 百丽餐厅 所以字符被删除 只保留 A Z a z 0
  • 使用 Javascript/Node.js 在代码内执行 mongoimport

    node js javascript 中是否有任何库可供个人使用mongoimport在代码中 据我了解 mongoimport 有点像 exe 您必须先执行它 然后才能使用其文本输入环境 是否可以在我的代码中执行 mongoimport
  • 如何绕过Access-Control-Allow-Origin?

    我正在一个平台上对我自己的服务器进行ajax调用 他们设置了阻止这些ajax调用的平台 但我需要它从我的服务器获取数据以显示从我的服务器数据库检索到的数据 我的 ajax 脚本正在运行 它可以将数据发送到我的服务器的 php 脚本以允许其处
  • 如何在打字稿中使用外部js

    我通过 Typescript 代码生成 Angular JS 代码 在一种情况下 我需要将外部 JS 文件添加到我的打字稿文件中 并且需要访问 js 文件中的类 我像这样添加js文件
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • 如何从 Cloud Functions for Firebase 文件夹读取证书文件

    我正在尝试读取 certs 文件夹下的文件 如下所示 functions certs idp public cert perm 这是我用来读取文件的代码 fs readFileSync path join dirname certs idp

随机推荐