【问题标题】:Why am I getting this error: Uncaught TypeError: cannot read property 'john' of undefined为什么我会收到此错误:未捕获的类型错误:无法读取未定义的属性 'john'
【发布时间】:2013-09-13 12:11:29
【问题描述】:

我是 JavaScript 新手,可能没有使用正确的术语,所以请多多包涵。

http://jsbin.com/IPaDAJO/1/

我希望页面上显示以下内容 你好,我的名字是约翰史密斯,我今年 29 岁。您好,我叫 Suzie Alport,今年 24 岁。

我想了解为什么 Suzie 不能参考 John 的 greet 方法?

<script>
        var employees = {
            john: {
                name: "John Smith",
                age: 29,
                job: "web developer",
                greet: function(){
                    document.write("Hello my name is " + this.name + " and I am " + this.age + " years old. ");
                }
            },
            suzie: {
                name: "Suzie Alport",
                age: 24,
                job: "nursery assistant",
                greet: employees.john.greet
            }
        };
        employees.john.greet();
        employees.suzie.greet();
</script>

谢谢

【问题讨论】:

  • 在 JavaScript 中阅读变量 scopethis
  • @shennan:这与范围或this无关。
  • @T.J.Crowder 我在胡乱猜测,因为这样的错误通常是我的范围问题的结果。这是在他把代码 sn-p 之前...

标签: javascript object


【解决方案1】:

在您创建分配给suzie 属性的对象时,employeesundefined。在整个表达式完成之前评估属性初始值设定项。

这是上面发生的事情的顺序:

  1. 引擎创建一个名为employees 的变量,初始值为undefined
  2. 引擎创建一个空白对象(最终将分配给employees)。
  3. 引擎创建另一个空白对象(最终将成为john 属性值)。
  4. 它评估 "John Smith" 并在来自 #3 的空白对象上创建一个名为 name 的属性,并为其赋予该值。
  5. 它对agejobgreet 重复该过程。
  6. 它将该对象分配给上述#2 中对象的john 属性。
  7. 它创建另一个空白对象(变成suzie)。
  8. 它评估 "Suzie Alport" 并在来自 #7 的对象上创建一个名为 name 的属性,并为其赋予该值。
  9. 它对agejob 重复该过程。
  10. 它尝试计算表达式 employees.john.greet 并失败,因为 employeesundefined

如果你把它分成两部分,它会起作用(直到 document.write 把事情搞砸):

var employees = {
    john: {
        name: "John Smith",
        age: 29,
        job: "web developer",
        greet: function(){
            document.write("Hello my name is " + this.name + " and I am " + this.age + " years old. ");
        }
    }
};
employees.suzie = {
    name: "Suzie Alport",
    age: 24,
    job: "nursery assistant",
    greet: employees.john.greet
};
employees.john.greet();
employees.suzie.greet();

这是因为在我们尝试评估 employees.john.greet 之前,对上面 #2 中创建的对象的引用已分配给 employees 变量。


旁注:

避免在现代网页和应用程序中使用document.write。相反,请使用DOM methodsdocument.write 仅在初始页面加载期间按照您可能希望的方式工作;初始页面加载后,它将完全清除现有文档并开始在同一窗口中写入新文档。

例如,您可以像这样将段落附加到document.body

function display(msg) {
  var p = document.createElement('p');
  p.innerHTML = String(msg);
  document.body.appendChild(p);
}

Live Example 与上述两者 (source)

【讨论】:

  • 谢谢,您的某个步骤中是否有错字。步骤 8 应为:它评估“Suzie Alport”并在来自 ** #7 ** 的对象上创建一个名为 name 的属性,并为其赋予该值。
  • @Abdi:谢谢。当我插入第 1 步时(我差点忘了!)我可以发誓有两个地方需要更新,但我只找到了一个。那是另一个。 :-)
猜你喜欢
  • 2015-11-04
  • 2021-10-06
  • 1970-01-01
  • 2019-04-30
  • 2015-10-10
  • 2016-10-05
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多