Вы можете присоединить событие к элементу при динамическом создании с помощью jQuery(html, attributes)
.
Начиная с jQuery 1.8, любой метод экземпляра jQuery (метод
jQuery.fn
) можно использовать как свойство объекта, переданного второму параметру:
function handleDynamicElementEvent(event) { console.log(event.type, this.value) } // create and attach event to dynamic element jQuery("
Ну, единственное, что я могу рассказать вам, это getters:
var foo = {
a: 5,
b: 6,
get c () {
return this.a + this.b;
}
};
foo.c; // 11
Это синтаксическое расширение, введенное спецификацией ECMAScript 5th Edition, синтаксис поддерживается большинством современных браузеров (в том числе IE9).
только ради свойств объекта мыслящего объекта из временной шкалы:
var foo = {
a: function(){return 5}(),
b: function(){return 6}(),
c: function(){return this.a + this.b}
}
console.log(foo.c())
также есть более высокие ответы . Вот как я модифицировал пример кода, с которым вы допросили.
UPDATE:
var foo = {
get a(){return 5},
get b(){return 6},
get c(){return this.a + this.b}
}
// console.log(foo.c);
var foo = { get a(){return 5}, get b(){return 6}, get c(){return this.a + this.b} }
, так что теперь вы можете просто сделать foo.c
вместо foo.c()
:) (Не стесняйтесь вставлять это в свой ответ, чтобы форматирование было лучше!)
– Joe
6 December 2016 в 06:42
Другие ответы, опубликованные здесь, лучше, но вот альтернатива:
init()
или код вне литерала объекта Автономные анонимные функции и хранение окон
var foo = {
bar:(function(){
window.temp = "qwert";
return window.temp;
})(),
baz: window.temp
};
Порядок гарантирован (bar
до baz
).
Конечно, он загрязняет window
, но я не могу представить, чтобы кто-то писал сценарий, который требует window.temp
быть постоянным. Может быть, tempMyApp
, если вы параноик.
Это также уродливо, но иногда полезно. Например, когда вы используете API с жесткими условиями инициализации и не чувствуете себя рефакторингом, поэтому область обзора верна.
И конечно, конечно.
Вы могли бы сделать это так
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 как объект, содержащий функцию печати, вы позволяете функции ссылаться на этот объект. Это означает, что вам не нужно «связывать» функцию печати с объектом, если вам нужно передать ее в другое место.
Если бы вы использовали this
, как показано ниже
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, вы гарантируете, что печать всегда будет возвращать один и тот же объект независимо от контекста, в котором выполняется функция. При использовании собственной версии createMyObject()
приведенный выше код будет работать только отлично и log 0, 1, 2 и 3.
, если ваш объект написан как функция, возвращающая объект, и вы используете методы атрибута объекта-объекта ES6, тогда это возможно:
const module = (state) => ({
a: 1,
oneThing() {
state.b = state.b + this.a
},
anotherThing() {
this.oneThing();
state.c = state.b + this.a
},
});
const store = {b: 10};
const root = module(store);
root.oneThing();
console.log(store);
root.anotherThing();
console.log(store);
console.log(root, Object.keys(root), root.prototype);
Примечание. Это решение использует TypScript (вы можете использовать vanilla JS, который TS компилирует, если необходимо)
blockquote>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'; }; } }
Вы могли бы сделать что-то вроде:
var foo = {
a: 5,
b: 6,
init: function() {
this.c = this.a + this.b;
return this;
}
}.init();
Это была бы какая-то однократная инициализация объекта.
Обратите внимание, что вы фактически назначаете возвращаемое значение init()
до foo
, поэтому вы должны return this
.
delete this.init
до return this
, чтобы [f 3] не был загрязнен
– Billy Moon
26 July 2011 в 02:12
init()
был непосредственно добавлен в литерал, чтобы сохранить его в одном выражении. Но, конечно, вы можете вызвать функцию отдельно от вас.
– Felix Kling
26 July 2016 в 19:51
Как об этом решении это будет работать и с вложенными объектами с массивом
Object.prototype.assignOwnProVal
= function (to,from){
function compose(obj,string){
var parts = string.split('.');
var newObj = obj[parts[0]];
if(parts[1]){
parts.splice(0,1);
var newString = parts.join('.');
return compose(newObj,newString);
}
return newObj;
}
this[to] = compose(this,from);
}
var obj = { name : 'Gaurav', temp :
{id : [10,20], city:
{street:'Brunswick'}} }
obj.assignOwnProVal('street','temp.city.street');
obj.assignOwnProVal('myid','temp.id.1');
Некоторое закрытие должно иметь дело с этим:
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()
.
Я использую следующий код как альтернативу, и он работает. И переменная также может быть массивом. (@ Fausto R.)
var foo = {
a: 5,
b: 6,
c: function() {
return this.a + this.b;
},
d: [10,20,30],
e: function(x) {
this.d.push(x);
return this.d;
}
};
foo.c(); // 11
foo.e(40); // foo.d = [10,20,30,40]
Существует несколько способов сделать это; это то, что я бы использовал:
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
Для завершения в ES6 у нас есть классы (поддерживаемые на момент написания этого только в последних браузерах, но доступные в Babel, TypeScript и других транспилерах)
class Foo {
constructor(){
this.a = 5;
this.b = 6;
this.c = this.a + this.b;
}
}
const foo = new 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 в соответствии с вашими потребностями.
}();
, она сама выполнит и вернет объект, а не функцию. Кроме того, foo.c
- это функция, поэтому запись в нее блокирует эту функцию, а следующий вызов через fooObject.c()
завершится с ошибкой. Возможно, эта скрипка ближе к тому, что вы собираетесь делать (это тоже синглтон, не предназначенный для создания экземпляра).
– Hollister
26 December 2013 в 03:24
Создание новой функции в вашем литерале объекта и вызов конструктора кажется радикальным отходом от исходной проблемы, и это не нужно.
Вы не можете ссылаться на свойство sibling во время инициализации литерала объекта.
var x = { a: 1, b: 2, c: a + b } // not defined
var y = { a: 1, b: 2, c: y.a + y.b } // not defined
Простейшее решение для вычисляемых свойств (без кучи, без функций, без конструктора):
var x = { a: 1, b: 2 };
x.c = x.a + x.b; // apply computed property
Бросок в опцию, так как я не видел этого точного сценария. Если вы не хотите, чтобы c
обновлялся при обновлении a
или b
, тогда ES6 IIFE работает хорошо.
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));
Поскольку мне нужно установить свойство для indexOfSelectedTier
, и мне нужно использовать это значение при настройке свойства hasUpperTierSelection
, я сначала вычисляю это значение и передаю его как параметр для IIFE
Очевидный простой ответ отсутствует, поэтому для полноты:
Но есть , любой способ иметь значения в свойствах объекта литерала зависит от других объявленных свойств раньше?
Нет. Все решения здесь откладывают до тех пор, пока объект не будет создан (по-разному), а затем назначит третье свойство. Простейший способ состоит в том, чтобы просто сделать это:
var foo = { a: 5, b: 6 }; foo.c = foo.a + foo.b;
Все остальные - более косвенные способы сделать то же самое. (Felix's особенно умный, но требует создания и уничтожения временной функции, добавления сложности и либо оставляет дополнительное свойство для объекта, либо [если вы
delete
это свойство] влияет на производительность последующего свойства доступ к этому объекту.)Если вам нужно, чтобы все были в одном выражении, вы можете сделать это без временного свойства:
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);
this
объекта доступен только для методов i> указанного объекта, и никаких других видов свойства. Любая идея, где я мог бы это найти? Благодаря!
– David Kennell
5 May 2018 в 01:27
Вот аккуратный путь ES6:
var foo = (o => ({
...o,
c: o.a + o.b
}))({
a: 5,
b: 6
});
console.log(foo);
Я использую его, чтобы сделать что-то вроде этого:
const constants = Object.freeze(
(_ => ({
..._,
flag_data: {
[_.a_flag]: 'foo',
[_.b_flag]: 'bar',
[_.c_flag]: 'oof'
}
}))({
a_flag: 5,
b_flag: 6,
c_flag: 7,
})
);
console.log(constants.flag_data[constants.b_flag]);
Теперь в ES6 вы можете создавать ленивые кешированные свойства. При первом использовании свойство оценивает один раз, чтобы стать обычным статическим свойством. Результат: во второй раз пропущена служебная служебная функция.
Магия находится в геттере.
const foo = {
a: 5,
b: 6,
get c() {
delete this.c;
return this.c = this.a + this.b
}
};
В стрелочке геттер this
поднимает окружающий лексический охват .
foo // {a: 5, b: 6}
foo.c // 11
foo // {a: 5, b: 6 , c: 11}
Object.defineProperty(foo, 'c', {get:function() {...}})
для их определения. Это легко сделать ненавязчивым способом на заводе, таком как этот. Конечно, если вы можете использовать сахар get
, это более читаемо, но возможности там есть.
– Aluan Haddad
18 April 2017 в 01:56
Просто создайте анонимную функцию:
var foo = new function () {
this.a = 5;
this.b = 6;
this.c = this.a + this.b;
};
new Point(x, y)
, за исключением того, что функция не названа для повторного использования.
– zzzzBov
1 August 2015 в 16:54
var foo = function() { this.…; return this; }.call({});
, который синтаксически не сильно отличается, но семантически разумен.
– Bergi
1 August 2015 в 19:13
new
использовалось для создания экземпляра функции как экземпляра. foo
будет объектом после назначения, а не функцией. Повторите оценку ваших комментариев и голосов.
– zzzzBov
11 March 2016 в 15:55
foo.a
илиfoo.b
будут изменены, значениеfoo.c
также изменится синхронно. Это может быть или не быть тем, что требуется. – HBP 2 May 2015 в 06:21