Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
function MyType (foo, bar)
{
var instance = Object.create(MyType.prototype);
instance._foo = foo;
instance._bar = bar;
return instance;
}
// работают оба варианта:
new MyType(1, 2);
MyType(1, 2);
function MyType (foo, bar)
{
if (this instanceof MyType)
{
this._foo = foo;
this._bar = bar;
}
else
{
return new MyType(foo, bar);
}
}
Дэвид Херман объясняет автонаследование в своей книге Effective JavaScript.А чтобы кто-нибудь случайно не подумал, что именно Херман и придумал этот трюк, я посвящу три абзаца рассмотрению хронологии событий.
"use strict" нужно было закончить статью.foo = Foo()
var my_model = Model();
// Error: _r or some other minified shit is undefinedvar that = this instanceof MyClass ? this : Object.create(MyClass.prototype);
that. Передача объекта arguments в другую функцию приводит к деоптимизации функции.arguments лучше вообще дел не иметь, а если и иметь — только получение элемента по индексу, длины и передача в apply.function Fubar (foo, bar){
if (!(this instanceof Fubar)){
throw new TypeError('Fubar is a constructor');
}
/* … */
}
this._superclass.apply(this, arguments) это не помешает.Если фунция — исключительно конструктор, то нечего вызывать её как просто функцию.
function Dict(props){
var dict = Object.create(null);
return Object.assign(dict, props);
}
function Dict(props){
Object.assign(this, props);
}
Dict.prototype = Object.create(null);
Dict.prototype[Symbol.iterator] = function(){ /* ... */}
new? :)// Обычный конструктор
array.map(function(it){
return new MyConstructor(it);
});
// Самовызавыющийся конструктор
array.map(MyConstructor);
Object.defineProperty(Function.prototype, 'new', {
get: function(){
var Ctor = this;
return function(...args){
return new Ctor(...args);
}
}
});
// ...
array.map(MyConstructor.new);
`array.map(x => new MyConstructor(x))` всё же лучше — кода не больше, поведение явное, нет зависимостей от стороннего АПИ в прототипах.Фабрика должна создавать и проводить другие операции над обьектами через статические методы: `Dict.create` `Dict.resolve` и так далее.
Dict.resolve({/* ... */}).А если уж там что то себе передумали в архитектуре и захотели убрать фабрику, то да, нужно перелопачивать код. Даже с простым рефакторингом нужно перелопачивать код, а уж с архитектурой тем более нужно.
нет зависимостей от стороннего АПИ в прототипах
Dict, а не Dict.create — не ко мне. В любом случае, не менее выразительно и, главное, куда более кратко.создаёт объект Dict, так почему без newМожет потому, как в данном случае он создаёт объект без прототипа, а конструкторы так не умеют? :) Да мало ли почему — фабрика.
сами же видите, что у вас бы возникли проблемы с созданием через конструкторВозникли бы, если не использовать самовызывающийся конструктор. Без всяких хаков.
Вообщем, со стороны возникает много вопросов.А на аналогичные
Object или Array не возникают. Или что там у нас нонче самое популярное, jQuery? Сама очевидность в плане возвращаемого значения основного метода.new, т.е., конструктор вызывается как функция. Вы же приводите пример обратного: из функция вызывается как конструктор. Никто же не мешает чуть-чуть подправить исходную функцию Dict:function Dict(props){
var dict = Object.create(Dict.prototype);
return Object.assign(dict, props);
}
Dict.prototype = …
Function.prototype.new, начиная с ES6 мы же вроде как можем fn[Symbol.create]() (ссылка на черновик спеки). Или нет? Если я неправ, то буду рад, если вы меня поправите, пионеров ES6 ещё не так уж много.new», статья здесь почти не причем.new на подобном значительно быстрее Object.create.Symbol.create создаёт объект из прототипа конструктора и устанавливает, если нужно, скрытые свойства, а не вызывает внутренний метод [[Construct]]. Он предназначен, скорее, для наследования встроенных конструкторов. Его судьба в ES6 туманна. А пример с Function.prototype.new отсюда.
[Перевод] Проблема конструкторов JavaScript и три способа её решения