Это должно быть countMe
, а не countMe.Increment()
, так как вы назначаете возвращаемое значение функции для countMe
function enclosedFunction(){
var counter = 0;
var Increment = function(){
counter ++;
console.log(counter);
}
return(Increment);
}
var countMe = enclosedFunction();
console.log("Count Me: ");
countMe();
Если вы хотите получить доступ с точечной нотацией, вам нужно использовать объект
function enclosedFunction(){
var counter = 0;
var Increment = function(){
counter ++;
console.log(counter);
}
return(Increment);
}
var countMe = {}
countMe.Increment = enclosedFunction();
console.log("Count Me: ");
countMe.Increment();
Нет. Кроме того, Вы могли принять лямбду как аргумент, который также дает Вам полный контроль, в котором назовут часть процесса "создания". Таким образом, можно назвать его как:
MyClass instance = MyClass.FactoryCreate(c=>
{
c.SomeProperty = something;
c.AnotherProperty = somethingElse;
});
Создавание выглядело бы подобным:
public static MyClass FactoryCreate(Action<MyClass> initalizer)
{
MyClass myClass = new MyClass();
//do stuff
initializer( myClass );
//do more stuff
return myClass;
}
Другая опция состоит в том, чтобы возвратить разработчика вместо этого (с неявным оператором броска в MyClass). Как который Вы звонили бы:
MyClass instance = MyClass.FactoryCreate()
.WithSomeProperty(something)
.WithAnotherProperty(somethingElse);
Проверьте это на разработчика
Обе из этих версий проверяются во время компиляции и имеют полную поддержку intellisense.
Третья опция, которая требует конструктора по умолчанию:
//used like:
var data = MyClass.FactoryCreate(() => new Data
{
Desc = "something",
Id = 1
});
//Implemented as:
public static MyClass FactoryCreate(Expression<Func<MyClass>> initializer)
{
var myclass = new MyClass();
ApplyInitializer(myclass, (MemberInitExpression)initializer.Body);
return myclass ;
}
//using this:
static void ApplyInitializer(object instance, MemberInitExpression initalizer)
{
foreach (var bind in initalizer.Bindings.Cast<MemberAssignment>())
{
var prop = (PropertyInfo)bind.Member;
var value = ((ConstantExpression)bind.Expression).Value;
prop.SetValue(instance, value, null);
}
}
Это - середина между проверенным во время компиляции и не проверенное. Действительно требуется некоторую работу, поскольку это вызывает константное выражение на присвоениях. Я думаю, что что-либо еще - изменения подходов уже в ответах. Помните, что можно также использовать нормальные присвоения, рассмотреть, нужно ли Вам действительно какое-либо из этого.
+1 на "Нет".
Вот является альтернатива анонимному объекту путем:
var instance = MyClass.FactoryCreate(
SomeProperty => "Some value",
OtherProperty => "Other value");
В этом случае FactoryCreate()
было бы что-то как:
public static MyClass FactoryCreate(params Func<object, object>[] initializers)
{
var result = new MyClass();
foreach (var init in initializers)
{
var name = init.Method.GetParameters()[0].Name;
var value = init(null);
typeof(MyClass)
.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
.SetValue(result, value, null);
}
return result;
}
Нет, объектный инициализатор может только привыкнуть на вызове к "новому" с конструктором. Одна опция могла бы состоять в том, чтобы добавить некоторый дополнительный args к Вашему методу фабрики, установить те значения при создании объекта в фабрике.
MyClass instance = MyClass.FactoryCreate(int someValue, string otherValue);
Как все сказал, нет.
Лямбда как аргумент была уже предложена.
Более изящный подход должен был бы принять анонимное и устанавливать свойства согласно объекту. т.е.
MyClass instance = MyClass.FactoryCreate(new {
SomeProperty = someValue,
OtherProperty = otherValue
});
Это было бы намного медленнее, хотя, так как над объектом нужно будет размышлять для всех свойств.
Нет, это - что-то, что можно только сделать 'встроенный'. Вся функция фабрики может сделать для Вас, должен возвратить ссылку.