Javascript 对象文本/初始值设定项中的自引用

Javascript 对象文本/初始值设定项中的自引用,javascript,object-literal,Javascript,Object Literal,有没有办法让下面这样的东西在JavaScript中工作 var foo = { a: 5, b: 6, c: this.a + this.b // Doesn't work }; 在当前表单中,此代码显然抛出了一个引用错误,因为this没有引用foo。但是,有没有办法让对象文本的属性中的值依赖于前面声明的其他属性?那么,我唯一能告诉您的是: var foo={ a:5, b:6, 获取c(){ 返回这个.a+这个.b; } } console.log(foo.c)/

有没有办法让下面这样的东西在JavaScript中工作

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

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

那么,我唯一能告诉您的是:

var foo={
a:5,
b:6,
获取c(){
返回这个.a+这个.b;
}
}

console.log(foo.c)//11
好吧,我唯一能告诉你的是:

var foo={
a:5,
b:6,
获取c(){
返回这个.a+这个.b;
}
}

console.log(foo.c)//11
您可以执行以下操作:

var foo = {
   a: 5,
   b: 6,
   init: function() {
       this.c = this.a + this.b;
       return this;
   }
}.init();
这将是对象的某种一次性初始化


请注意,您实际上是将
init()
的返回值赋值给
foo
,因此您必须
返回该值

,您可以执行以下操作:

var foo = {
   a: 5,
   b: 6,
   init: function() {
       this.c = this.a + this.b;
       return this;
   }
}.init();
这将是对象的某种一次性初始化


请注意,您实际上是在将
init()
的返回值赋值给
foo
,因此您必须
返回该值

有几种方法可以实现这一点;这就是我要使用的:

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

有几种方法可以实现这一点;这就是我要使用的:

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 foo = {
    a: 5,
    b: 6
};
foo.c = foo.a + foo.b;
所有其他方法都只是做同样事情的更间接的方法。(Felix的特别聪明,但需要创建和销毁一个临时函数,增加了复杂性;或者在对象上留下一个额外的属性,或者[如果你
删除该属性]该对象上的后续属性访问。)

如果需要将其全部放在一个表达式中,则可以不使用临时属性:

var foo = function(o) {
    o.c = o.a + o.b;
    return o;
}({a: 5, b: 6});
当然,如果您需要多次这样做:

function buildFoo(a, b) {
    var o = {a: a, b: b};
    o.c = o.a + o.b;
    return o;
}
然后在需要使用它的地方:

var foo = buildFoo(5, 6);

缺少显而易见的简单答案,因此为了完整性:

但是有没有办法让对象文本的属性中的值依赖于前面声明的其他属性

不可以。这里的所有解决方案都将其延迟到对象创建之后(以各种方式),然后指定第三个属性。最简单的方法就是这样做:

var foo = {
    a: 5,
    b: 6
};
foo.c = foo.a + foo.b;
所有其他方法都只是做同样事情的更间接的方法。(Felix的特别聪明,但需要创建和销毁一个临时函数,增加了复杂性;或者在对象上留下一个额外的属性,或者[如果你
删除该属性]该对象上的后续属性访问。)

如果需要将其全部放在一个表达式中,则可以不使用临时属性:

var foo = function(o) {
    o.c = o.a + o.b;
    return o;
}({a: 5, b: 6});
当然,如果您需要多次这样做:

function buildFoo(a, b) {
    var o = {a: a, b: b};
    o.c = o.a + o.b;
    return o;
}
然后在需要使用它的地方:

var foo = buildFoo(5, 6);

您可以使用模块模式来完成。就像:

var foo = function() {
  var that = {};

  that.a = 7;
  that.b = 6;

  that.c = function() {
    return that.a + that.b;
  }

  return that;
};
var fooObject = foo();
fooObject.c(); //13
使用此模式,您可以根据需要实例化多个foo对象


您可以使用模块模式来完成。就像:

var foo = function() {
  var that = {};

  that.a = 7;
  that.b = 6;

  that.c = function() {
    return that.a + that.b;
  }

  return that;
};
var fooObject = foo();
fooObject.c(); //13
使用此模式,您可以根据需要实例化多个foo对象


只需实例化一个匿名函数:

var foo = new function () {
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
};

只需实例化一个匿名函数:

var foo = new function () {
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
};

你可以这样做

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定义为包含打印函数的对象,可以允许函数引用该对象。这意味着,如果需要将打印函数传递到其他地方,则不必将其“绑定”到对象

如果您愿意,请使用
,如下所示

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()
的自版本时,上述代码将正常运行并记录0、1、2和3

你可以这样做

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定义为包含打印函数的对象,可以允许函数引用该对象。这意味着,如果需要将打印函数传递到其他地方,则不必将其“绑定”到对象

如果您愿意,请使用
,如下所示

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()
的自版本时,上述代码将正常运行并记录0、1、2和3

一些闭包应该解决这个问题

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

    return {
        a: a,
        b: b,
        c: c
    }
}();
foo
中声明的所有变量都是
foo
的私有变量,正如您对任何函数声明所期望的那样,并且因为它们都在范围内,所以它们都可以相互访问,而无需引用
,就像您对函数所期望的那样。不同之处在于,此函数返回一个对象,该对象公开私有变量并将该对象分配给
foo
。最后,使用
return{}
语句只返回要作为对象公开的接口

然后,该函数在末尾执行
()
,这将导致对整个foo对象进行求值,所有
var foo = ((a,b) => ({
    a,
    b,
    c: a + b
}))(a,b);
let processingState = ((indexOfSelectedTier) => ({
    selectedTier,
    indexOfSelectedTier,
    hasUpperTierSelection: tiers.slice(0,indexOfSelectedTier)
                         .some(t => pendingSelectedFiltersState[t.name]),
}))(tiers.indexOf(selectedTier));
class asd {
    def = new class {
        ads= 'asd';
        qwe= this.ads + '123';
    };

    // this method is just to check/test this solution 
    check(){
        console.log(this.def.qwe);
    }
}

// these two lines are just to check
let instance = new asd();
instance.check();
class asd {
    def = new class {
        ads= 'asd';
        qwe= this.ads + '123';
    };
var asd = {
    def : {
        ads:'asd',
        qwe: this.ads + '123';, //ILLEGAL CODE; just to show ideal scenario
    }
}
class CONSTANT {
    static readonly PATH = new class {
        /** private visibility because these relative paths don't make sense for direct access, they're only useful to path class
         *
         */
        private readonly RELATIVE = new class {
            readonly AFTER_EFFECTS_TEMPLATE_BINARY_VERSION: fs.PathLike = '\\assets\\aep-template\\src\\video-template.aep';
            readonly AFTER_EFFECTS_TEMPLATE_XML_VERSION: fs.PathLike = '\\assets\\aep-template\\intermediates\\video-template.aepx';
            readonly RELATIVE_PATH_TO_AFTER_EFFECTS: fs.PathLike = '\\Adobe\\Adobe After Effects CC 2018\\Support Files\\AfterFX.exe';
            readonly OUTPUT_DIRECTORY_NAME: fs.PathLike = '\\output';
            readonly INPUT_DIRECTORY_NAME: fs.PathLike = '\\input';
            readonly ASSETS_DIRECTORY_NAME: fs.PathLike = '\\assets';
        };
    }
}
{ 
  a: ...,
  b: "${this.a + this.a}",
}
const foo = {};
foo.a = 5;
foo.b = 6;
foo.c = foo.a + foo.b;  // Does work
foo.getSum = () => foo.a + foo.b + foo.c;  // foo.getSum() === 22
var x = {
    a: (window.secreta = 5),
    b: (window.secretb = 6),
    c: window.secreta + window.secretb
};