【问题标题】:Javascript Can't Call Push On Array Inside Another Function [duplicate]Javascript无法在另一个函数内调用推送数组[重复]
【发布时间】:2014-07-25 01:38:17
【问题描述】:

我有一个非常简单的 JavaScript 问题...

我有一个函数,Pets,它包含三个变量:一个整数、一个字符串和一个数组,定义如下:

function Pets() {
    var index;
    var name;
    var animals = ["cat", "dog"];
}

在这个函数下面的另一个函数中,我声明了一个 Pets 类型的变量并将“鼠标”推到 animals 数组上。然后我做一个控制台日志来查看这些值。

function Test() {
    ...
    var pets = new Pets();
    pets.index = 1;
    pets.name = "My Pets";
    pets.animals.push("mouse");
    console.log(pets);
}

无论出于何种原因,我都没有看到控制台的任何输出。

然后我在调用 animals.push 之前和之后添加了更多控制台日志记录:

    var pets = new Pets();
    pets.index = 1;
    pets.name = "My Pets";
    console.log("BEFORE PUSH");
    console.log(pets);
    pets.animals.push("mouse");
    console.log("AFTER PUSH");

这是我的输出:

BEFORE PUSH
Pets {index: 1, name: "My Pets"} 

请注意,我只看到第一个控制台日志而不是第二个(推送之后),我认为这表明在 animals 上调用 push 存在问题。

还请注意,控制台输出显示 Pets 有一个名为 index 的属性和一个名为 name 的属性,但它没有表明还有一个名为 的属性>animals 这是我的数组。

我尝试将数组声明更改为:

var animals = new Array();

但这似乎也没有帮助。

在我可以将元素推送到动物数组之前,我必须做一些特别的事情来初始化动物数组吗?更一般地说,为什么动物属性甚至不作为 Pets 类的一部分出现?

谢谢,

一月

【问题讨论】:

  • 我想它是在其他地方被问到的。然而,快速搜索并没有得到答案。我想我的搜索词不正确。删除!
  • 在 Stack Overflow 上复制问题会降低我的声誉吗? :O
  • 不,它只是将您的问题标记为重复问题,并且问题上方会出现一个横幅,将用户重定向到原始问题。您的 reputation 没有任何变化
  • 好的...好吧,我接受了你的回答,所以希望它能坚持下去。 :)

标签: javascript arrays function push undefined-behavior


【解决方案1】:

您声明变量的方式不会使它们在 Pets 构造函数之外可见

这就是为什么您看不到第二个控制台的原因,因为该行

pets.animals.push("mouse");

会抛出错误TypeError: Cannot read property 'push' of undefined(或类似的,取决于浏览器)。这将导致脚本的其余部分停止执行。

您在第一个控制台日志中看到 indexname 的唯一原因是您在创建 Pets 对象后在对象上创建它们。您需要使用 this 运算符或在原型上设置它们来声明它们

function Pets() {
    this.index = null;
    this.name = null;
    this.animals = ["cat", "dog"];
}

【讨论】:

  • 所以我需要先声明它们然后初始化它们?如下:var this.index = null?
  • 在声明对象属性时不要使用var,否则可以
  • 哦,好吧。那么仅仅放置 this.index = null 就意味着初始化和“声明”对象属性?
  • pets 也没有push 属性,所以你可能需要Array.prototype.push.apply(pets,["mouse"]); 来做它
  • @13ruce1337,没有 OP 调用而不是 pets 对象上而不是动物数组对象上的 push 方法
【解决方案2】:

您是否尝试过在声明期间将变量分配给窗口而不是使用 var?将其设置为 window.myVar = ["var1", "var2"]

【讨论】:

  • 将变量放在全局对象上是一种不好的做法,因为您可能会不小心覆盖已经存在的属性。
  • 好的。我会接受你的建议,然后谢谢!
【解决方案3】:

您无法通过这种方式访问​​ Pets 的任何属性,因为它们不会暴露给外部函数。您正在通过说来创建属性索引和名称

pets.index = ...

你必须像这样改变你的代码:

function Pets() {
    this.index;
    this.name;
    this.animals = ["cat", "dog"];
}
function Test() {
    var pets = new Pets();
    pets.index = 1;
    pets.name = "My Pets";
    pets.animals.push("mouse");
    console.log(pets);
}
Test();

【讨论】:

  • 是的...现在明白了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
相关资源
最近更新 更多