javascript中的双括号是啥意思以及如何访问它们

Posted

技术标签:

【中文标题】javascript中的双括号是啥意思以及如何访问它们【英文标题】:What do double brackets mean in javascript and how to access themjavascript中的双括号是什么意思以及如何访问它们 【发布时间】:2015-05-09 02:47:09 【问题描述】:

情况

我有以下使用 Promise 的功能。

var getDefinitions = function() 
    return new Promise(function(resolve) 
        resolve(ContactManager.request("definition:entities"));
    );


var definitions = getDefinitions()

definitions的内容是:

Promise 
    [[PromiseStatus]]: "resolved",
    [[PromiseValue]]: child

直接访问PromiseValue属性返回undefined

var value = definitions.PromiseValue; // undefined

问题

双括号[[ ]] 是什么意思,如何检索[[PromiseValue]] 的值。

【问题讨论】:

了解您使用的是哪个库会有所帮助。 嗯,我想我正在使用内置的 javascript 库和 Chrome (??) 看起来这就是 promise 状态的描述方式。您可以在 Chrome 的控制台中尝试此操作:new Promise(function())。 Chrome 的[[PromiseStatus]] 可以与Firefox 的<state> 进行比较。我真的不明白这里的问题是什么(假设 OP 知道什么是承诺)。 @Jeff 据我所知,这就是 Chrome 向您展示承诺状态的方式。这些属性故意在对象外部不可见。如果您在 Firefox 中查看 Promise 对象,它不会以这种方式呈现它。我认为它可能只是为了作为诊断辅助工具。 ContactManager.request("definition:entities") 是什么? 【参考方案1】:

[[]]里面的东西是什么

我的问题是双括号 [[ ]] 是什么意思,以及如何检索 [[PromiseValue]] 的值。

这是一个内部属性。您无法直接访问它。原生 Promise 只能在 then 中使用 Promise 或异步解包 - 请参阅 How to return the response from an asynchronous call。引用规范:

本规范定义它们纯粹是为了说明目的。 ECMAScript 的实现必须表现得好像它以此处描述的方式生成和操作内部属性。 内部属性的名称用双方括号 [[ ]] 括起来。当算法使用对象的内部属性并且对象没有实现指示的内部属性时,会抛出 TypeError 异常。

你不能

说真的 - 它们是什么?

非常好!正如上面的引用所说,它们只是在规范中使用 - 所以它们没有理由真正出现在您的控制台中。

不要告诉任何人,但这些确实是私人符号。它们存在的原因是其他internal 方法能够访问[[PromiseValue]]。例如,当 io.js 决定返回 Promise 而不是采用回调时 - 这将允许它快速访问这些属性,以防万一。它们暴露在外面。

我可以访问它们吗?

除非您自己制作 Chrome 或 V8 版本,否则不会。也许在带有访问修饰符的 ES7 中。截至目前,没有办法,因为它们不是规范的一部分,并且会跨越浏览器 - 抱歉。

那么我如何获得我的价值呢?

getDefinitions().then(function(defs)
    //access them here
);

但是如果它返回一个错误呢?在这些情况下,在 .then() 的末尾(和外部)添加以下内容。

.catch(function(defs)
    //access them here
);

虽然如果我不得不猜测 - 你是 not converting the API correctly to begin with 因为这种转换仅在方法同步的情况下才有效(在这种情况下不返回承诺)或者它已经返回承诺将使其解决(这意味着您根本不需要转换 - 只需 return

【讨论】:

此外,应该说它完全违背了Promise 访问then 之外的包装值的目的。 Promise 的目的是从非阻塞函数的缺失返回值中抽象出来,即 Promise 代表“未来值”。一旦暴露了这个“未来价值”(then 之外),整个计算过程中这些抽象将立即丢失。 如果承诺被拒绝,那么这些值将通过.catch((values) => )而不是.then(() => )获得 @Benjamin,您的意思是说内部槽和内部方法是由 JS 引擎按照规范实现的吗?我读过一个answer 说,它们只是文字,没有实现。 (可能是我在这里误解了)另外,我不是在承诺的背景下询问,因为我现在对此不太了解。只是问一般像 [[PUT]] [[Prototype]] 等 @Number945 通常,devtools 中的[[PromiseValue]] 实际上是由 devtools 生成的 - 当您在控制台上按回车键时,它会执行 evaluateOnCallFrame,将消息发送到 V8,它返回一个 RemoteObject子类型promise。对此有明确的临时支持。上面的答案是正确的(检查员从那里获取这些属性)但不准确(这不是他们到达那里的方式 - 他们通过显式调试器支持到达那里)【参考方案2】:

我今天也走进了这个问题,碰巧找到了解决办法。

我的解决方案如下所示:

fetch('http://localhost:3000/hello')
.then(dataWrappedByPromise => dataWrappedByPromise.json())
.then(data => 
    // you can access your data here
    console.log(data)
)

这里,dataWrappedByPromise 是一个 Promise 实例。要访问Promise 实例中的数据,我发现我只需要使用.json() 方法unwrap 该实例。

希望有帮助!

【讨论】:

因为柯里化then(dataWrappedByPromise => dataWrappedByPromise.json()) === then(resp.json()) @jymbob 我无法理解您的评论。你说 cafemike 定义了一个箭头函数,这个定义可以用一个常量代替;具体来说,你说他的“then()”等价于“then(resp.json())”。首先,“resp”从何而来?更重要的是,参数“resp.json()”会立即执行,因此传递给“.then()”的参数是任何常量(字符串、对象或数字)在 promise 仍未解决时执行的结果。也许你不明白 ".then()" 需要一个函数作为它的参数。 @IAM_AL_X 嗯。我也无法理解我的评论。两年后我唯一能想到的就是我的意思是引用“console.log”行并且完全打错了。 .then(data => console.log(data)) 可以简化为 .then(console.log) 是正确的,但您绝对正确的是,需要该函数才能访问该函数的常量。很抱歉有任何困惑【参考方案3】:

这个例子是用 react 的,但是大部分应该是一样的。

用你的 url 替换 this.props.url 以使其适用于大多数其他框架。

解析 res.json() 会返回 [[promiseValue]] 但是,如果您随后将其返回到下面的另一个 .then() 方法,则可以将其返回为一个总数组。

let results = fetch(this.props.url)
        .then((res) => 
            return res.json();
        )
        .then((data) => 
            return data;
        )

【讨论】:

【参考方案4】:

阅读the manpage,我们可以看到:

根据设计,承诺的即时状态和价值不能 从代码同步检查,无需调用then() 方法。

为了帮助调试,仅在检查承诺对象时 手动,您可以看到更多信息作为特殊属性 无法从代码中访问(目前,这是由 随机化属性名称,因为缺少更复杂的 语言或调试器支持)。

强调我的。因此,你想做的事是做不到的。更好的问题是为什么你需要像那样访问承诺状态?

【讨论】:

【参考方案5】:

尝试使用 await

代替

var value = definitions.PromiseValue 

使用

var value =  await definiton;

这可能会通过产生承诺值来解决您的目的。

请注意, await 只能在异步函数中使用,它是 ES2016 特性。

【讨论】:

你能解释一下这个解决的目的吗?谢谢!【参考方案6】:

我认为这会很顺利。

(async () => 
  let getDefinitions = await ( () => 
    return new Promise( (resolve, reject) => 
      resolve(ContactManager.request("definition:entities"));
    );
  )();
)();

【讨论】:

【参考方案7】:

对于返回的响应是 HTML,而不是 JSON 的情况

fetch('http://localhost:3000/hello')
  .then(response => response.text())
  .then(data => 
    // you can see your PromiseValue data here
    console.log(data)
  )

【讨论】:

以上是关于javascript中的双括号是啥意思以及如何访问它们的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript/jQuery 中括号中的代码块是啥意思? [复制]

javascript中的for(;;)后面的括号中的符号是啥意思?

Pig中的双冒号到底是啥意思?

将对象文字包装在箭头函数中的括号是啥意思? [复制]

dockerfile中的双箭头(<<:*django)是啥意思?

AWS ELB 中的双栈前缀是啥意思?