有什么方法可以让下面的东西在JavaScript中工作?

var foo = {
    a: 5,
    b: 6,
    c: this.a + this.b  // Doesn't work
};

在当前的表单中,这段代码显然抛出了一个引用错误,因为它没有引用foo。但是有没有办法让对象字面量的属性值依赖于之前声明的其他属性呢?


当前回答

某种终结应该能解决这个问题;

var foo = function() {
    var a = 5;
    var b = 6;
    var c = a + b;

    return {
        a: a,
        b: b,
        c: c
    }
}();

在foo中声明的所有变量对foo来说都是私有的,就像你在任何函数声明中所期望的那样,因为它们都在作用域中,所以它们都可以相互访问,而不需要引用this,就像你在函数中所期望的那样。不同之处在于这个函数返回一个对象,该对象公开私有变量并将该对象赋值给foo。最后,使用return{}语句返回希望作为对象公开的接口。

然后,函数在结束时使用()执行,这将导致整个foo对象被求值,其中的所有变量被实例化,返回对象被作为foo()的属性添加。

其他回答

如果你想使用原生JS,其他答案提供了很好的解决方案。

但是如果你愿意写自引用对象,比如:

{ 
  a: ...,
  b: "${this.a + this.a}",
}

我写了一个叫做self- references -object的npm库,它支持这种语法并返回一个原生对象。

下面是对象中'this'行为的一个例子。

this.prop = 'external';
global.prop = 'global.prop';
const that = this;

const a = {
  prop: 'internal',
  prop1: this.prop, //external

  log() {
    return this.prop //internal
  },
  log1: () => {
    return this.prop //external
  },
  log2: () => {
    return function () {
      return this.prop; //'global.prop' in node; 'external' in chrome
    }()
  },
  log3: function () {
    return (() => {
      return this.prop; //internal
    })()
  },
}
var x = {
    a: (window.secreta = 5),
    b: (window.secretb = 6),
    c: window.secreta + window.secretb
};

这与@slicedtoad的答案几乎相同,但没有使用函数。

有几种方法可以做到这一点;这是我要用的:

function Obj() {
 this.a = 5;
 this.b = this.a + 1;
 // return this; // commented out because this happens automatically
}

var o = new Obj();
o.b; // === 6

你可以这样做

var a, b
var foo = {
    a: a = 5,
    b: b = 6,
    c: a + b
}

当我必须引用函数最初声明的对象时,该方法已被证明对我有用。以下是我如何使用它的一个最小示例:

function createMyObject() {
    var count = 0, self
    return {
        a: self = {
            log: function() {
                console.log(count++)
                return self
            }
        }
    }
}

通过将self定义为包含print函数的对象,允许函数引用该对象。这意味着如果您需要将print函数传递到其他地方,则不必将其“绑定”到对象。

如果您愿意,可以使用下面所示的方法

function createMyObject() {
    var count = 0
    return {
        a: {
            log: function() {
                console.log(count++)
                return this
            }
        }
    }
}

然后下面的代码将记录0,1,2,然后给出一个错误

var o = createMyObject()
var log = o.a.log
o.a.log().log() // this refers to the o.a object so the chaining works
log().log() // this refers to the window object so the chaining fails!

通过使用self方法,可以保证print总是返回相同的对象,而不管函数在什么环境中运行。当使用createMyObject()的self版本时,上面的代码将正常运行并记录0、1、2和3的日志。