【问题标题】:Value assigned to primitive will be lost分配给原语的值将丢失
【发布时间】:2016-10-21 18:17:50
【问题描述】:

如果我有一个对象数组,并循环遍历它们,为每个对象分配一个属性值,WebStorm 会警告我:

分配给原语的值将丢失

但是,在控制台中进行测试时,我不会“丢失”任何值。

这只发生在循环位于函数内部时。

下面是这个错误的一个例子:

let people = [
    {
        name: 'Foo',
        age: 21,
        surname: 'FooBar'
    },

    {
        name: 'Bar',
        age: 51,
        surname: 'FooBar'
    }
];

没有函数包装:

people.forEach(function (person) {
    person.surname = 'Baz'; // No error. Works in console.
});

使用函数包装器:

function changeSurname(people) {
    people.forEach(function (person) {
        person.surname = 'Baz'; // Error warning me that value assigned to primitive will be lost.
    });
}

changeSurname(people);

这两者在控制台中产生相同的输出(姓氏更改为“baz”)。

我认为这与对象引用以及 person 指向的内容有关,但我不确定具体是什么。

为什么我会看到这个错误?

WebStorm 试图拯救我的潜在错误是什么?

【问题讨论】:

  • 让变量成为常量,使内部对象基本类型。如果您需要更改其中的值,请不要使其成为常量,使用var 声明变量
  • @AkshayKhandelwal 我不相信这是真的。即使使用var,我仍然会收到错误消息。 const 使事情保持不变。 let 将变量范围限定为块范围。
  • @Rayon 但这是我的困惑,据我所知,价值没有丢失。如果您复制代码(带有函数包装器的代码),则姓氏会正确更改。我是否误解了丢失的内容?因为我没有看到任何价值丢失。
  • @MattLishman,surname 对象持有的早期值丢失了..IDE 试图说即使它是函数的参数,它也是通过引用传递的,因此 object 将更新!
  • @Rayon 啊,我明白了!我误解了它指的是哪个值。鉴于更新对象正是我想要做的,这是一个相当烦人的错误......那么这种编码风格有什么问题吗? (这可能是另一个 SO 问题)

标签: javascript webstorm


【解决方案1】:

您的代码没有什么不妥之处,WebStorm 的类型推断有点混乱(JavaScript 的这方面特别令人困惑)。

它的 linter 看到一个字符串并假设你会尝试这样的事情:

var primitive = "september";
primitive.vowels = 3;

primitive.vowels;
// => undefined

这会导致“丢失”价值。

它只捕获函数内部的这个“错误”这一事实似乎是一个应该报告的彻底错误。

为了进一步了解 JavaScript 的这个奇怪部分,我推荐 Angus Croll 的优秀深入文章 here

【讨论】:

  • 我找不到这方面的错误报告。但是,我不能再在更高版本的 WebStorm 上复制它。不幸的是,我不记得我看到这个错误的版本,但它似乎已经解决了!
  • 我正在使用 webstorm,当前的最新版本,我遇到了同样的问题。
  • 2021:WebStorms 行为仍然存在
【解决方案2】:

如果您使用方括号,JetBrains 编辑器 (WebS/PhpS) 不会显示任何错误。

person['surname'] = 'Baz';

【讨论】:

  • 这其实是不一样的。这将使用变量surname。你的意思是person['surname'](注意引号)?
  • 是的,我很着急,忘记了引号!它应该修复编辑器错误。还要检查你的编辑器是否更新到最新版本
  • 我的 webstorm 在复制我的代码时似乎不再显示错误。你的呢?不幸的是,这意味着我无法测试这是否解决了问题。
  • 是的,确实如此,这就是我找到您的帖子的方式,但我在上面发布的内容已解决。这可能是一种特殊情况。
  • 然后 eslint 会用 ..is better written using in notation. 捕获它 :)
【解决方案3】:

我也遇到了同样的问题。

您也可以要求 WebStorm 禁用对下一行的检查,但我决定改用 for of 循环:

for (person of people) {
    person.surname = 'Baz';
}

结果它实际上使我的代码更具可读性,所以我很高兴。

【讨论】:

    【解决方案4】:

    我在使用角度自定义指令时遇到了类似的问题。

    下面是我的自定义指令:

    function customDirective() {
          return {
            scope: {
              model: '='
            }
            link: function(scope) {
                    scope.resetModel = function() {
                        scope.model.name = null;   //In these lines I was getting the above 
                        scope.model.email = null;  //mentioned warning in webstorm.
                    }
                }
          }
    }
    

    在查看$compile docs 之后,我决定使用下面的代码来解决这个警告,并且可以很好地绑定到子作用域和父作用域,当然可以,除非你的模型是对象引用。

    function customDirective() {
           return {
             scope: {
                model:'<' // Please refer the above linked angular docs for in detail explanation.
             }
             link: function(scope) {
                scope.resetModel = function() {
                   scope.model.name = null;
                   scope.model.email = null;
                }
             }
          }
    }
    

    【讨论】:

    • 虽然这可能对其他人有用,但它并不能真正回答我的问题。我的问题与角度无关。 (而且 Webstorm 无论如何也不理解角度到那个级别)
    • 不知道为什么这被否决了。我发现这个答案正在寻找同样的问题。我认为当您声明一个未使用或未返回的变量时会触发警告,intellij 认为这没有意义,但这只是因为它对双向绑定一无所知。
    • @MattLishman 这个问题与 Angular 无关。如果您想扩展将= 更改为&lt; 时会发生类似情况的情况,请在其他地方进行,这只会浪费我的时间,可能还会浪费很多其他人的时间。
    • @ClintEastwood 你打算在那里回复我吗?
    猜你喜欢
    • 1970-01-01
    • 2016-11-22
    • 2017-08-27
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多