简体   繁体   English

使用`this`的JS对象给出了不确定的结果

[英]JS object using `this` gives an undefined result

Ok here is a very simple JS object. 好的,这是一个非常简单的JS对象。 Three attributes are strings, the fourth is a function. 字符串是三个属性,第四个是函数。

var myStringBuilder = {
  protocol: "http://",
  host: "www.mysite.com",
  fullPath: this.protocol + this.host + "/just/for/fun/",
  getFullString: function() {
    return this.fullPath;
  }
}

console.log(myStringBuilder.getFullString());  // Returns "NaN/just/for/fun"

In fullPath , this.protocol and this.host are both undefined. fullPaththis.protocolthis.host均未定义。 Why does this happen? 为什么会这样?

jsfiddle jsfiddle

Internally JavaScript objects are constructed based on a hashing algorithm. 内部JavaScript对象是基于哈希算法构造的。 So, they keys may not logically appear in the order we define them. 因此,它们的键可能不会按照我们定义它们的顺序在逻辑上出现。 In this case, fullPath gets defined first and when the value is assigned, it depends on partOne and partTwo where they havn't got defined yet. 在这种情况下,将首先定义fullPath ,并且在分配值时,取决于尚未定义它们的partOnepartTwo That is why they are undefined while defining fullPath . 这就是为什么在定义fullPath undefined它们的fullPath

If you must construct an Object like this, I would recommend a constructor function, like this 如果您必须像这样构造一个对象,我会推荐一个像这样的构造函数

function MyStringBuilder() {
    this.protocol = "http://";
    this.host = "www.mysite.com";
    this.fullPath = this.protocol + this.host + "/just/for/fun/";
}

MyStringBuilder.prototype.getFullString = function() {
    return this.fullPath;
}

myStringBuilder();

The advantage of this method is that, you can customize the object creation dynamically. 此方法的优点是,您可以动态自定义对象的创建。 For example, you can pass protocol or host values like this 例如,您可以像这样传递protocolhost

function MyStringBuilder(protocol, host) {
    this.protocol = protocol || "http://";
    this.host     = host     || "www.mysite.com";
    this.fullPath = this.protocol + this.host + "/just/for/fun/";
}

with this change, you should be able to decide the protocol and host at runtime. 通过此更改,您应该能够在运行时确定protocolhost

To get around part of the hash being undefined, you can use functions instead of calculated values. 要解决部分哈希值未定义的问题,可以使用函数代替计算所得的值。 This will delay evaluation. 这将延迟评估。

var myStringBuilder = {
  partOne: "http://",
  partTwo: "www.mysite.com",
  fullPath: function(){ return this.partOne + this.partTwo + "/just/for/fun/" }
}

如果我在以前的答案的所有有价值的信息,同意回答对问题的精确点,该fullPath属性定义不正确,因为它不是在一个函数上下文初始化,所以this并不是指对象myStringBuilder。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM