Динамическая композиция струн - PullRequest
0 голосов
/ 27 ноября 2018

Можно ли как-нибудь составить строку динамически?Я прочитал немного о передаче по значению и передаче по ссылке, и поэтому я создаю все строки как объекты.

Пример:

var foo = {str: 'foo'};
var bar = {str: foo.str + 'bar'};
var baz = {str: bar.str + 'baz'};
foo.str = 'fuu';
console.log(baz.str); //expected 'fuubarbaz', got 'foobarbaz

Спасибо взаранее!

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Это не работает, конкатенация foo.str + была выполнена только один раз, знак плюс не является функцией, которая вызывается несколько раз.

Один из способов сделать то, что вы хотите, это создатьобъект с 3 строками и методом!:

const obj = {
    a: 'foo',
    b: 'bar',
    c: 'baz',
    show: function() {
        return this.a + this.b + this.c;
    }
};

console.log(obj.show());
obj.a = 'fuu';

console.log(obj.show());
0 голосов
/ 27 ноября 2018

Основываясь на ответе Пудди, я придумал следующее:

console.clear()
var foo = {
  // _str is the storage of str
  _str: 'foo',
  // getter of str, always called when accessing str in a read context
  get str() {return this._str}, 
  // setter of str, always called when accessing str in a write context
  set str(str) {this._str = str}
};
// read context, so get str() of foo is called
console.log(foo.str) // "foo"

var bar = {
  // define getter function of bar, calls getter function of foo
  get str() {return foo.str + 'bar'}
};
// read context, so get str() of bar is called
console.log(bar.str) // "foobar"

var baz = {
  // define getter function of baz, calls getter function of baz
  get str() {return bar.str + 'baz'}
};
// read context, so get str() of baz is called
console.log(baz.str) // "foobarbaz"

// write context, so set str(str) of foo is called.  foo._str is now 'fuu', was 'foo'
foo.str = 'fuu';

// read context, getter of baz is called which calls getter of bar which calls getter of foo which returns _str which has the value of 'fuu'
console.log(baz.str); // "fuubarbaz"

В качестве альтернативы вы можете использовать Object.defineProperty :

console.clear();

var foo = Object.defineProperty({}, 'str', {
  enumerable: true,
  get: () => this._property_str, 
  set: (str) => this._property_str = str
});

var bar = Object.defineProperty({}, 'str', {
  enumerable: true,
  get: () => foo.str + 'bar', 
});

var baz = Object.defineProperty({}, 'str', {
  enumerable: true,
  get: () => bar.str + 'baz', 
});



foo.str = 'foo'
console.log(foo.str) // "foo"
console.log(bar.str) // "foobar"
console.log(baz.str) // "foobarbaz"
foo.str = 'fuu';
console.log(baz.str); // "fuubarbaz"
0 голосов
/ 27 ноября 2018

Нет, когда вы определите такие вещи статически, они будут использовать переменную, когда она была вызвана.Вы можете сделать что-то подобное с getters , хотя:

let foo = {str: 'foo'};
let bar = {get str() { return foo.str + 'bar'; }};
let baz = {get str() { return bar.str + 'baz'; }};
foo.str = 'fuu';
console.log(baz.str); // properly outputs `fuubarbaz`

Причина, по которой это работает, - магия добытчиков;вместо статического определения свойства вы определяете функцию, которая вызывается при попытке доступа к свойству.Таким образом, он может «реагировать» на любые последующие изменения, потому что он всегда генерируется динамически.

...