Pull to refresh

Comments 68

если нужен класс с инициализацией то можно сделать так:

var popup= function () { this.initialize.apply(this, arguments); };
popup.prototype = {
initialize: function (h) { /** вызывается при инициализации**/ } ,
show: function (text) { ... } ,
close: function () { ... }
}
}

теперь можно делать так
var p=new popup({caption:'Alert'}); //вызывается инициализация класса в которую передаем параметры
p.show('Hello');
p.close();


давно еще подсмотрел это в prototype, теперь постоянно пользуюсь.
это как альтернатива если не делать через
var pop=function(par){


}

имхо так читабельней когда инициализация вынесена в отдельную ф-цию
Может и читабельней, но приходится явно ее вызывать. Это не очень красиво.
Вы что-то не поняли.
В плане пользования все выглядит одинаково
var p=new popup(params);

отличие только в коде класса
Вот я и говорю — в «коде класса», как вы это называете, ее приходится явно вызывать.
это всего лишь один раз в коде
> в «коде класса», как вы это называете
ну хорошо… имитация класса :)
Ну это какбэ конструктор.
Обычно тогда используется либа. что-то типа такого:

var Class = function (Parent, proto) {
	if (proto == null) {
		proto = Parent;
		Parent = null;
	}
	var Constructor = function () {
		this.initialize.call( this, arguments );
	};
	
	F.prototype = Parent.prototype
	
	Constructor.prototype = new F();
	Constructor.prototype.constructor = Child;
	Constructor.parent     = Parent;
};

var Foo = Class({
	initialize: function () {
		// constructing here
	},
	fooMethod: function () {
		// fooMethod here
	}
});

var Bar = Class(Foo, {
	initialize: function () {
		Bar.parent.initialize.apply( this, arguments );
		
		// construction here
	},
	
	barMethod: function () {
		var f = this.fooMethod();
		// barMethod here
	}
});
Ну, имеет право на жизнь в таком случае, да:)
Я вообще слабо понимаю, как сейчас можно писать на JS без фреймворков)
Классы и наследование — это частные случаи code reuse. JS предлагает «из коробки» кучу других способов повторно использовать код — миксины, агрегация… Тысячи их, ну вы-то знаете:) Все обладают своими минусами и плюсами, все нуждаются в той или иной степени в «сахаре». Можно выбирать, в общем. Дело вкуса и частных случаев.

Ни в коем случае не умаляя достоинства фреймворков, я все же предпочитаю делать столько, сколько могу, непосредственно встроенными в язык средствами.
Угу, так построен Class.create в prototype.
И приблизительно так же в MooTools)
А если Вы имеете в виду лишнюю прослойку function () { this.initialize.apply(this, arguments); };
то это такие пустяки в плане производительности, что не вижу смысла на этом экономить.
Просто эта строчка будет повторяться в неизменном виде во всех ваших конструкторах. Вас это не коробит?
в моем микро-фреймвоке это вызывается =$class();
var pop=$class();
так что не коробит
спасибо, она у меня вторая на очереди после JavaScript Patterns :)
Good Parts более базовая. Хотя Patterns ее во многом повторяет, но не во всем.
UFO just landed and posted this here
Побойтесь бога, орайлевские переводные книги в бумажном виде у нас стоят около тысячи рублей. А в электронном виде вообще не купить.
Вам жалко 600 рублей за хорошую книгу, которая поможет вам профессионально вырасти?
я бы вам прислал этот пдф, благо у этого «жадного издателя» они без DRM, если бы ваша тяга к знаниям превосходила вашу тягу к халяве.
А что, я неправду сказал?
Не минусовал, но подозреваю, что минусуют за то, что учите людей жить. При этом — грубо.
Я считаю грубостью, когда меня пытаются использовать вместо гугла. Да еще «нахаляву».
Грубостью отвечать на грубость — это не оправдание ;)
Вы, конечно, правы. «Насилие — последнее прибежище некомпетентного», и все такое. Но, знаете, когда я очень устаю, то у меня не хватает сил оставаться рафинированным интеллигентом:) И на хамство хочется ответить хамством.
В такие моменты идеальный выход — это промолчать)
Нагрубить в ответ, в принципе, тоже выход)
UFO just landed and posted this here
> 2100 рублей
Вот видите, не так уж они жадные:) Да, это перебор.

Я тоже не люблю покупать книги, особенно бумажные.

Выслал вам в личку ссылку на PDF.
UFO just landed and posted this here
Да, очень бы хотелось.
Напишите автору — я бедный студент из снежной России, последние деньги потратил на водку для медведя, а очень хочется стать крутым джаваскриптером, как вы, пришлите вашу книжку, пожалуйста.
Ну, про водку, пожалуй, лишнее, но вообще может и прокатить.
Ага, крутым джаваскриптером — чтобы зарабатывать много, — но не тратить.
Отличный пост, спасибо! Всё грамотно изложено, способствует систематизации ранее накопленных знаний.
Да, эта книга перевернула мои взгляды на Javascript. Все, что я знаю, почерпнуто оттуда.
Я ее купил в пятницу. Пока ничего радикально нового не узнал, но денег не жалко.
Мне она просто попалась в руки в нужный момент. Всегда сложно совершить прыжок от новичка к продвинутому пользователю. К тому моменту я знал синтаксис JS (невеликий подвиг), но многое было непонятно — что это за зверь prototype, что делать без наследования, статических функций и т.д. Так что эта книжка — как первая любовь, на всю жизнь.
Я бы посоветовал еще JavaScript: The Good Parts Крокфорда, но, боюсь, после «Patterns» там ничего нового не найдете.
Потрясающий язык с множеством подводных камней. На первый взгляд простой синтаксис скрывает в себе кучу говна.
arguments.callee? o_O может всетаки не стоит уже этим пользоваться? имхо
Хорошая статья для начинающих.
А вот с этим
>Его достаточно легко освоить
Я бы поспорил. :) Прототипы, миксины, передача аргументов by sharing… Он прост на первый взгляд. Я не первый год пишу на нем и до сих пор иногда случаются «озарения» :)
PS Недавняя новость про запуск линукса в js эмуляторе просто взорвала мозг. Что-то до сих пор на место не встало.
А вы говорите, легко освоить…
PPS Я бы перефразировал — с ним легко начинать. И если распробуешь его — несложно расти.
Полностью согласен. Сложность (и сила) JS в том, что у него своя, особенная парадигма. Главная задача при овладении JS — перестроить мозг с класс-ориентированного программирования на прототип-ориентированное и функциональное.

P.S. Под «достаточно легко освоить» подразумевал «прикрутить JQuery и радоваться новым свистелкам и перделкам на своем сайте»
>>с оператором new. Что случится, если забыть этот оператор? Интерпретатор не выдаст предупреждений, но это приведет к логическим ошибкам

Меня одного коробят подобные фразы? Интерпретатор начнет ругаться при первой же попытке вызвать метод прототипа.
А что случится если скобки забыть? Тоже ведь ошибки не будет. Почему тут не предусмотрена защита?

Неужели я чего то не понимаю и городить кучу лишнего кода для подобной “защиты от дурака” считается нормальным?

И чем меньше кода — тем читабильнее и легче воспринимается. И с классами та же история. Много лишнего кода, исключительно для сахара. Чем не устраивает прототипное наследование? Абсолютно все те же возможности.
Согласен. Всегда считал, что «Простое лучше, чем сложное» (с)
И чем меньше кода — тем читабильнее и легче воспринимается. И с классами та же история. Много лишнего кода, исключительно для сахара. Чем не устраивает прототипное наследование? Абсолютно все те же возможности.

Либы просто предоставляют удобную обёртку для уменьшения количества конечного кода, не более того. Это то же самое прототипное наследование. Не понимаю, чего некоторые люди стараются убедить других, что «используешь обёртку — не прототипное наследование, а хрень». Смысл много раз писать длинное слово «prototype»? Смысл много раз дублировать код, если его можно врапнуть в библиотеку, тем более, это полезно скажется на окончательном коде. Зачем вы усложняете?
F.prototype = Parent.prototype
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.parent = Parent;
Конечно от случая зависит много и от того что внутри Parent, но зачастую достаточно
Child.prototype = new Parent();

Хотя конечно если нужна именно куча “классов”. И обычное наследование не подходит — то конечно проще враппер.
К тому же автокомплит никто не отменял если слово prototype уж слишком длинное.
Обычное наследование — это какое? Я, вроде, показал обычное.
prototype длинное не только для письма, но и для чтения) да ещё и дублирующееся имя класса. Да и вес окончательного файла.
я предпочитаю не задумываться над деталями и большим количеством «если» и следовать принципу KISS. =)
Обычное это которое через экземпляр объекта родителя.
Через экземпляр объекта родителя вызывается конструктор, а там может быть код, который не должен вызываться «зря» или должен вызываться только с параметрами.
Так поэтому и написал выше что зависит от того что внутри Parent
Меня одного коробят подобные фразы? Интерпретатор начнет ругаться при первой же попытке вызвать метод прототипа.
А что случится если скобки забыть? Тоже ведь ошибки не будет. Почему тут не предусмотрена защита?


Это может быть удобно в фреймворке. Например, как мог бы выглядеть jQuery:

var $ = function (selector, context) {
	if (! (this instanceof $)) {
		return new $(selector, context);
	}
	this.find( selector, context );
};

$.fn = $.prototype = {
	// prototype here
};


В итоге получится такой вызов:

var $divs = $('div');
// эквивалентно:
var $divs = new $('div');


То есть, доллар-функция как-бы получилась фабрикой для самой-себя.
ну и зачем в итого два эквивалента одного и того же? Исключительно ради красоты кода?
ИМХО В том же jQuery — постороенном на краткости кода и благоприятствующем созданию цепочек — имеет смысл только фабрика.

И писать лишний код — пусть его тут и всего пара строк, ради того чтобы можно было создавать объекты ещё и через new — лишнее.
в jQuery фабрика именно и создаёт объекты через new. И, кстати, jQuery можно вызывать через new, будет работать ;) Там именно такой подход и используется, только содержимое конструктора вынесено в $.prototype.init
Работать то будет. Я к тому что смысла в этом по сути нет. И если бы такой возможности не было — вряд ли бы кто то стал кидаться в него помидорами.
Дело в том, что «new» — необходимо, чтобы был доступ к прототипу, а «без new» — сахар, чтобы был круче результат.
new там разве не внутри $? И от внешнего new никак не зависит, если внутри все равно отдельная фабрика со своим new?

Я в кишках jQuery не ковырялся, поэтому тут спорить не буду
Я недавно описывал.
$ на самом деле создаёт инстанс $.prototype.init, который на самом деле есть инстансом $. Та всё немного запутанно.
Если вы не против, я вам покажу на примере AtomJS:
var dom = function (sel, context) {
	if (! (this instanceof dom)) {
		return new dom(sel, context);
	}
	// initialize
}


dom на самом деле класс, который надо вызывать через new dom('tag.class'), но ради упрощения api я добавил возможность не писать «new»: dom('tag.class'). С таким же успехом я мог вынести содержимое dom в какую-то функцию-конструктор, но зачем? ;)
Ну например, чтобы не плодить вариантов использования. Но в целом понятно
кстати, а не проще ли сделать так:

var myFunc = function()
{
//используем this
}
myFunc = new myFunc();


получается синлтон) — он всегда будет доступен только как объект, добавить нужно одну строчку сразу за определением, и никаких проверок при каждом вызове.
Синглтон — плохой паттерн, а в JS — вообще не нужен. То, что вы описали можно очень легко сократить:
var myFunc = new function()
{
//используем this
}


Тем более для jQuery одиночка не подходит совершенно. Там обязан каждый раз инициироваться новый объект.
странная аргументация — «плохой паттерн».
если я знаю, что объект у меня должен быть гарантированно один на странице, то очень даже неплохой.

за шорткат спасибо, не додумался)
В строгом режиме стандарта ECMAScript 5 this в этом случае не будет указывать на глобальный объект. Посмотрим, как можно избежать этой ошибки, если ECMAScript 5 недоступен.


Простите, но мне кажется, что вы — неправы. Строгий режим распространяется только на функции, вызванные при помощи call или apply:

(function () {
	var test = function () {
		console.log(this);
	};

	test(); // window
	test.call(null); // window
})();


(function () {
	'use strict';

	var test = function () {
		console.log(this);
	};

	test(); // window
	test.call(null); // null <=========
})();
Вот что я прочитал в спецификации ECMA 5:
If this is evaluated within strict mode code, then the this value is not coerced to an object. A this value of null or undefined is not converted to the global object and primitive values are not converted to wrapper objects. The this value passed via a function call (including calls made using Function.prototype.apply and Function.prototype.call) do not coerce the passed this value to an object.

Я понимаю это как «Значение this в строгом режиме не приводится к объекту. Если this имеет значение null или undefined, this не будет приведено к глобальному объекту. Если значение this базового типа, оно не будет преобразовано в соответствующий объект. Значение this, переданное через вызов функции (в том числе, вызовы через Function.prototype.apply и Function.prototype.call), не будет преобразовано в объект.» В стандарте нет ограничений по способу вызова.

Однако в Chromium 11.0.696.65 все так, как Вы и описываете. В Firefox 4.0.1 в строгом режиме прямой вызов печатает в консоль undefined, вызов через Function.prototype.callnull. Я опирался на стандарт, но любой стандарт разбивается о практику :(
А ещё говорят что C++ не очевиден и содержит много подводных камней. Javascript, PHP и т.п. вот где настоящий ад! Компиляции нет, на этом этапе ошибок не словить. Типизация неявная. Проверяем только тестами. Интерпретатор в любой момент может выкинуть ошибку в рантайме. >_<
Типизация — утиная, JavaScript не содержит подводных камней, просто люди не могут его понять. И да, в C++ тоже может быть ошибка в рантайме.
Конечно, может. Только часть ошибок всё же отсеивается на этапе компиляции, что уже является огромным подспорьем. Например, в случае отсутствия метода в классе будет ошибка сразу, а не чёрт знает когда.

Хоть в С++ есть куча своих недостатков, но при грамотном подходе (не устраивать опасные игры с указателями и т.п.) ошибки получится словить раньше. Обычно ещё до запуска программы.

А в скриптовых языках (я вообще, а не только про JS), жить без тестов невозможно совершенно, потому что в любой момент можно получить а-та-та.

Но я не сравниваю конкретно эти языки. Я вообще про подход к программированию. Везде свои неудобства, свои преимущества, но мне как человеку который долго программировал на компилируемых языках со статической типизацией привыкнуть к закидонам скриптовых с динамических очень уж непросто.
Существует замечательная книжка от Николаса Закаса, «Professional JavaScript».
Там описаны простым языком и очень доступно почти все основные методы наследования, включая смешанные прототипно-конструкторные, паразитические и др. Рекомендуется как дополнение к статье, вернее, как основа, а статья — дополнение.
Sign up to leave a comment.

Articles