为什么(function(){return this;})。call('字符串常量')返回[String:'字符串常量']而不是'字符串常量'?

时间:2019-09-06 09:18:58

标签: javascript

这是我在尝试JS时的最新发现:

(function() { return this; }).call('string literal');
// => [String: 'string literal'] in V8
// => String { "string literal" } in FF

我在执行以下操作时偶然发现了这一点:

(function() { return this === 'string literal'; }).call('string literal');
// => false

有人能告诉我为什么函数内的this并不完全 是作为第一个参数传递给call的吗?

编辑1

What is the difference between string primitives and String objects in JavaScript?被标记为我的问题的可能重复项。

尽管两个问题的答案都与JS如何在对象内部包装原语有关,但我认为这些问题及其答案并不相同。

我的问题是“为什么传递给调用的参数和函数内部的this的值不同?”而另一个问题是“为什么代码块1比代码块2更快?”

我的问题的正确答案是“因为您未使用严格模式”,而另一个问题的答案与实现ECMAScript的引擎在内部如何快速访问数据有关。

我希望这个澄清是正确的?

2 个答案:

答案 0 :(得分:8)

.call在内部调用[[Call]],它执行

  
      
  1. 执行OrdinaryCallBindThis(F,calleeContext,thisArgument)。
  2.   

然后OrdinaryCallBindThis(设置将要调用的函数的this值)将以非严格模式将新的this包装在对象中:

  1. 如果thisMode严格,则将thisValue设为thisArgument。

  2. 其他,

    a。如果thisArgument未定义或为null,则...

    b。否则,让thisValue为! ToObject(thisArgument)。

在严格模式下,您会看到字符串 not 不会被包装在对象中:

'use strict';
(function() {
  console.log(this);
  console.log(this === 'string literal');
}).call('string literal');

答案 1 :(得分:3)

由于您要在字符串基元上调用方法,因此该方法会自动转换为字符串对象。

日志是两个控制台呈现字符串对象的方式。

进一步阅读:What is the difference between string primitives and String objects in JavaScript?