Comments 199
В JavaScript нет ассоциативных массивов в принципе.
я думаю автор имеет ввиду количество полей в объекте js
Каких полей?
var q = {};
Здесь length должно быть 0? Да не шутите, там уже есть поля.
var q = {};
Здесь length должно быть 0? Да не шутите, там уже есть поля.
Возможно стоит понимать, что хотя их называют хеши, в первую очередь они обьекты, и не стоит их использовать как ассоциативные массивы.
1. JSON — строка, и есть методы для преобразования из строки в данные.
2. JSON != Хеш в результате, там может быть и число и нул и массив
3. Если Вам нужно знать количество полей, возможно массив будет удобней
2. JSON != Хеш в результате, там может быть и число и нул и массив
3. Если Вам нужно знать количество полей, возможно массив будет удобней
Об этом и речь: авторы JS создали альтернативу хешам в виде plain object, но забыли добавить возможность посчитать количество элементов в этом импровизированном массиве.
посчитать количество ключей, не? (ECMAScript 5 правда)
Глупость. Объект в JS — это объект. Тот самый
Вот, посчитаете свойства в объекте? А вот и облом!
new stdClass
в PHP.$object = new stdClass();
$object->a = 1;
$object->b = 2;
$object->c = 3;
Вот, посчитаете свойства в объекте? А вот и облом!
Мысль верная, но очень легко из объекта достать все свойства, загнать в массив и посчитать их длинну. Короче, 2 функции, одна строчка.
Да, count() вернет 1 в данном случае :). Но в PHP никто не заставляет использовать объекты, как ассоциативные массивы: более того, у них в PHP разная семантика. А вот в JS выбор особо не дают
На самом деле заставляет. Мне лучше из метода класса вернуть объект, потому что тогда я смогу легко к ним обратиться:
method()->arrayKey
Ну тогда на ваш выбор и ArrayObject, и собственная реализация методов ArrayAccess/Countable, и SplКучаРазличныхСтруктур и т.п.
Если не ошибаюсь, в 5.4 обещали сделать для массивов тоже самое
Вам ключ принципиален? Почему-то когда я использую обьекты, то мне не важно количество ключей (конфиги, набор данных для связей разных обьектов) а когда мне нужно перечисление, то всегда удобней именно массив. Может стоит пользоваться данными по другому, чтоб не считать количество полей у обьекта?
Можно создать свой класс Hash, который будет поддерживать число пар как отдельно поле.
Можно создать функцию вида
Можно создать функцию вида
$.hashCount = function(hash) {
var count = 0;
$.each(hash, function() {
count++;
});
return count;
};
туда очень много чего забыли добавить, чтобы было хотя бы минимально юзабильно для программиста, в тех случаях, когда нужно выйти за пределы простенькой функции, подвешенной на событие в форме. кажется, потому-то и понадобились все эти фреймворки prototype да jquery.
я не знаю языка, где операции со строками и массивами были бы более комфортны и прозрачны, но уж точно это не javascript где с этим делом, вообще, хуже некуда.
вобщем, всецело поддерживаю вас! я, лично, очень люблю php и терпеть не могу когда всякие недоучки скороспелые обзывают его презрительными кличками за то, что он позволяет на себе писать таким же недоучкам как они сами))
я не знаю языка, где операции со строками и массивами были бы более комфортны и прозрачны, но уж точно это не javascript где с этим делом, вообще, хуже некуда.
вобщем, всецело поддерживаю вас! я, лично, очень люблю php и терпеть не могу когда всякие недоучки скороспелые обзывают его презрительными кличками за то, что он позволяет на себе писать таким же недоучкам как они сами))
Видимо имелись ввиду объекты. Которые, кстати, можно использовать почти так же как ассоциативные массивы.
var test = {a: 1, b: 2};
console.log( test['a'] + ' ' + test['b'] );
1. Не совсем понятно, что вы имеете ввиду говоря: «хоть в PHP и всё передается по значению»?
2. Сравнивать javascript и PHP наверное все-таки не совсем корректно, эти языки решают разные задачи: PHP — backend, JS — Frontend
2. Сравнивать javascript и PHP наверное все-таки не совсем корректно, эти языки решают разные задачи: PHP — backend, JS — Frontend
С появлением node.js это уже не столь очевидно…
да и PHP можно исполнять в браузере :)
это как?
JS-сервер написанный на PHP действительно есть, по аналогии с node.js.
А вот о интерпретаторе PHP на js гугл ничего не знает.
Но теоретически наверное можно, интересно.
А вот о интерпретаторе PHP на js гугл ничего не знает.
Но теоретически наверное можно, интересно.
code.google.com/p/phype/ ))
Есть для питона
code.google.com/p/pejs/
Но я их не тестил, если кто хочет — попробуйте.
Есть для питона
code.google.com/p/pejs/
Но я их не тестил, если кто хочет — попробуйте.
Скомпилировать php в llvm и загнать в emscripten? Только зачем? :)
То о чем я говорил вот, но оно очень старое и не дописанное:
phpjs.berlios.de/
phpjs.berlios.de/
human emulator разве что?
До появления node.js это тоже никогда не было очевидно. Самый известный случай — ASP, до ASP ещё была куча решений.
Про node.js уже ответили, а вот про передачу по значению… Ну об этом половина статьи: в PHP дохрена встроенных типов, и PHP умеет создавать копию для всех встроенных типов, кроме объектов. И когда вы передаете, скажем, массив в функцию на PHP, то создается копия массива специально для этой функции, и вы вольны внутри функции изменять этот массив, как вам угодно и при этом тот массив, который передали в качестве аргумента, не изменится. Это и есть передача по значению.
Спасибо, собственно на объекты я и намекал, что они передаются по ссылке.
Передача объекта и передача переменной по сслыке (с &) совершенно разные вещи
Объекты передаются не по ссылке. Всё-таки заставили меня привести пример… Нет, чтобы документацию почитать…
Этим и отличается передачи по значению и по ссылке
$obj = new stdclass;
$obj->some_property = 'lalala';
function some_func($obj) {
$obj = new stdclass;
}
function another_func_with_link(&$obj) {
$obj = new stdclass;
}
some_func($obj); // $obj не изменился
another_func_with_link($obj); // у $obj пропали все свойства
Этим и отличается передачи по значению и по ссылке
У $obj не пропали все свойства. просто переменной присвоилось другое значение. А объекты передаются по ссылке. Надо вам почитать документацию:
$foo = $obj = new stdclass;
$obj->some_property = 'lalala';
function some_func($obj) {
$obj->test = 123;
}
function another_func_with_link(&$obj) {
$obj = new stdclass;
}
some_func($obj->test); // $obj изменился
another_func_with_link($foo); // у $obj все свойства на месте
another_func_with_link($obj); // содержимое переменной $obj - другое
Видимо имелось ввиду
some_func($obj)
?М, ну, да, конечно же, я имел ввиду, что это стал другой объект. Я просто некорректно выразился.
Употребляя для передачи объектов и для передачи других переменных вместе с "&" одинаковое словосочетание «по ссылке», вы вводите людей в заблуждение. Так как это совершенно разные «по ссылке».
Кроме того, а как быть с простым присвоением? Тоже вводить дополнительный термин «присвоение по ссылке»?
Описание «все переменные передаются по значению, но для объектов значением является ссылка (указатель)» куда более чёткое и верное.
Кроме того, а как быть с простым присвоением? Тоже вводить дополнительный термин «присвоение по ссылке»?
Описание «все переменные передаются по значению, но для объектов значением является ссылка (указатель)» куда более чёткое и верное.
php5 — объекты по ссылке
php4 — объекты клонируются (в пхп5 clone();)
истина где-то рядом :)
php4 — объекты клонируются (в пхп5 clone();)
истина где-то рядом :)
Умники ставят умникам плюсики =) Не говорите больше глупостей, не заблуждайте молодых.
В первой функции Вы создали _новую_ переменную, это происходит неявно, ели Вы не будете извращаться а просто поменяете там свойство, то оно поменяется, в жс это решается с помощю var в пхп же это происходит неявно.
В первой функции Вы создали _новую_ переменную, это происходит неявно, ели Вы не будете извращаться а просто поменяете там свойство, то оно поменяется, в жс это решается с помощю var в пхп же это происходит неявно.
Я не очень корректно выразился, наверное, уж простите меня :)
Если смотреть на корректность, Вы выразились обратно пропорционально истине, обьект на самом деле пришел в обоих случаях по ссылке, просто в первом случае вы не его переписали а создали локальную переменную с таким же именем, а во втором случае вы насильно написали значение в то что пришло, на жс это выглядело бы так:
var obj = {'qwe':'asd'}
function func1(obj)
{
var obj = {};
}
function func2(obj)
{
obj = {};
}
func1(obj)// обьект не меняется
func2(obj)// обьект поменялся
var obj = {'qwe':'asd'}
function func1(obj)
{
var obj = {};
}
function func2(obj)
{
obj = {};
}
func1(obj)// обьект не меняется
func2(obj)// обьект поменялся
Между прочим, в вашем примере объект оба раза не поменяется. Потому что obj = {} во второй функции всё равно будет являться присвоением локальной переменной obj (аргумент функции) значения {}, что исходный объект никак не затронет, ибо {} это вообще новый объект
Да, Вы правы =) Вот с пхп тоже самое и произошло, но это ведь не значит что не передается по ссылке
Там написано что обьект присваивается по ссылке, передается в функцию по ссылке.
Или Вас смутила эта разница: ($a) = ($b) = и ($c,$d) =? Как ни крути а работают они одинаково — ссылаются на один обьект.
Или Вас смутила эта разница: ($a) = ($b) = и ($c,$d) =? Как ни крути а работают они одинаково — ссылаются на один обьект.
One of the key-points of PHP5 OOP that is often mentioned is that «objects are passed by references by default». This is not completely true.
;)
На заборе тоже написано много чего, я понимаю что это не ссылки, не указатели, но суть ведь не в названии, суть в том как это все работает. А работает это практически так же как и ссылки. В математике ведь можно на 0 делить, но в учебниках пишут что нельзя, почему? Чтоб не забивали себе голову ерундой.
В математике-таки нельзя делить на 0, потому что возникают проблемы при делении 0/0. Так что, пожалуйста, подучите матчасть и не спорьте с официальной документацией к PHP ;)
Раз уж Вы начали про официальную документацию переведу кусочек матчасти:
«When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.»
Перевод:
«Когда объект передается как аргумент, возвращается или присваивается другой переменной, переменные не одинаковы (не ссылки): они содержат копии идентификаторов, который указывает на один и тот же обьект.»
А теперь вспоминаем что такое ссылки:
Переменная которая не содержит значения а ссылается на него.
А теперь вопрос: Так в чем же разница?
Я сам отвечу: Разница в том, что в отличии от ссылок, в пхп переменные содержат айди обьекта.
А теперь обьясните мне разницу при работе, какая разница будет ссылка или обьект будет искаться по айди?
«When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.»
Перевод:
«Когда объект передается как аргумент, возвращается или присваивается другой переменной, переменные не одинаковы (не ссылки): они содержат копии идентификаторов, который указывает на один и тот же обьект.»
А теперь вспоминаем что такое ссылки:
Переменная которая не содержит значения а ссылается на него.
А теперь вопрос: Так в чем же разница?
Я сам отвечу: Разница в том, что в отличии от ссылок, в пхп переменные содержат айди обьекта.
А теперь обьясните мне разницу при работе, какая разница будет ссылка или обьект будет искаться по айди?
Ну я ведь приводил пример. Передача по ссылке в PHP — это когда пишется &$arg, что позволяет модифицировать исходную переменную. Если вы передадите объект $obj в качестве аргумента функции в PHP, то без "&" вы не сможете изменить значение $obj на что-то другое (например на строку) внутри функции. Т.е. любые изменения объекта, на который указывает $obj действительно будут видны извне, но саму переменную $obj поменять при этом нельзя — без явной передачи по ссылке вы не можете поменять значение этой переменной, например, сменить ей тип.
в математике на ноль делить можно только в пределе.
и проблема этого не в 0/0, а в том, что даже в пределе при делении константы на стремящуюся слева к нулю переменную будет минус-бесконечность, а при стремлении справа плюс-бесконечность. проблема 0/0 — последствия.
Поэтому есть символ «бесконечность без знака» (объединение плюс и минус бесконечности), которому и можно считать равным любое число, деленное на ноль, кроме нуля
Не путайте людей. На 0 делить нельзя. 0 — это конкретное число, которое не имеет знака. Когда же в пределе вы приближаетесь к 0, то получаете бесконечно малую величину отличную от 0. Так как она отлична от 0, то можно говорить о знаке этой величины.
Есть три вида передачи аргументов: по значению, по ссылке и по копии ссылки.
Объекты передаются в функцию именно по копии ссылки. Таким образом даже если внутри функции значение меняется — оно меняется только у этой копии. Внешние переменные не затрагиваются.
Объекты передаются в функцию именно по копии ссылки. Таким образом даже если внутри функции значение меняется — оно меняется только у этой копии. Внешние переменные не затрагиваются.
2. Как область применения языка влияет на такие внутрение нюансы как то, что значения переменных object-типа являются указателями на структуры в другой области памяти?
если по-вашему никак, то давайте что ли ассемблер с php и javascript сразу будем сравнивать
Ассемблеры разные, это раз. Второе, эти языки отличаются не назначением, а парадигмой. Процедурно можно писать и на PHP и на JS, но сила последнего, например, в прототипном ООП. И JS не единственный язык с прототипным ООП, однако только он один используется в вебе.
Область применения выражается в наборе стандартных библиотек, а не в особенностях языка. Например, классическая Java для веба вообще не пригодна, но есть расширение J2EE, которое не меняет функционал языка, но расширяет область его применения. Руби тоже изначально для веба вообще не позиционировался, но потом народ написал большую инфраструктуру, включая рельсы, рейк, пассажир и т.д. и язык стал очень даже пригодным для веба. Ну и перл для примера последнего — замена баша в консоли, по большому счёту.
Область применения выражается в наборе стандартных библиотек, а не в особенностях языка. Например, классическая Java для веба вообще не пригодна, но есть расширение J2EE, которое не меняет функционал языка, но расширяет область его применения. Руби тоже изначально для веба вообще не позиционировался, но потом народ написал большую инфраструктуру, включая рельсы, рейк, пассажир и т.д. и язык стал очень даже пригодным для веба. Ну и перл для примера последнего — замена баша в консоли, по большому счёту.
1) Ассемблер один, разные наречия. и отличие их только в наличии макросов, порядке аргументов, и прочих плюшках.
2) назначением эти языки тоже отличаются. в качестве frontend embedded жаваскрипт используют уже 15 лет, а node.js только 2 года. и если бы не решение Netscape'а 15-тилетней давности, то вряд ли Javascript сейчас имел хоть десятую часть популярности. если не нравится аналогия с ассемблером, приведу пример VB: динамический, объектно-ориентированный. почему бы с ним не сравнить?
3) что вы понимаете под «классической Java» и «позиционированием Ruby»? если критерий предназначенности для веба у языка — это наличие в названии намёка на этот самый веб, то PHP — единственный веб-ориентированный язык, который я знаю. тем не менее, он даже не первый.
4) на мой взгляд как раз тем, кто на JS пишут процедурно, и приходит в голову сравнивать его с PHP.
2) назначением эти языки тоже отличаются. в качестве frontend embedded жаваскрипт используют уже 15 лет, а node.js только 2 года. и если бы не решение Netscape'а 15-тилетней давности, то вряд ли Javascript сейчас имел хоть десятую часть популярности. если не нравится аналогия с ассемблером, приведу пример VB: динамический, объектно-ориентированный. почему бы с ним не сравнить?
3) что вы понимаете под «классической Java» и «позиционированием Ruby»? если критерий предназначенности для веба у языка — это наличие в названии намёка на этот самый веб, то PHP — единственный веб-ориентированный язык, который я знаю. тем не менее, он даже не первый.
4) на мой взгляд как раз тем, кто на JS пишут процедурно, и приходит в голову сравнивать его с PHP.
А процедурно на нём пишут почти все ;), из-за отсутствия понимания механизма прототипов и реализации прототипного наследования
1. Ассемблер — это вид компилятора. А языки к ним бывают какие угодно. Даже с ООП. Офигеть, да? Всё что делает ассемблер — это прямой перевод символьных операндов в точные бинарные эквиваленты (современные ассемблеры конечно немножко умнее, но всё-таки). Так как машины бывают разные, то и набор операндов и их возможности совершенно разные. Следовательно и ассемблеры разные.
2. ActionScript тоже frontend embedded и ему тоже не один день. И на нём пишут ничуть не меньше, чем на JS. На VB тоже писали, было время да прошло. Я сам на васике под бравсер кодил, офигеть! Место JS под Солнцем обусловлено только тем, что он единственный язык, который поддерживается во всех браузерах в боля-меня вменяемом виде.
3. Классическая Java не имела инструментов для разработки под веб. Вообще. Сервлеты и прочие умные слова появились намного позже. Изначально руби в вебе мог быть возможен только в виде CGI, что есть ололо, но со временем всё изменилось. Название тут ни при чём, я ведь уже написал: Область применения выражается в наборе стандартных библиотек, а не в особенностях языка.
4. Эти люди ничем не хуже тех, кто пытается засунуть классы в JS.
2. ActionScript тоже frontend embedded и ему тоже не один день. И на нём пишут ничуть не меньше, чем на JS. На VB тоже писали, было время да прошло. Я сам на васике под бравсер кодил, офигеть! Место JS под Солнцем обусловлено только тем, что он единственный язык, который поддерживается во всех браузерах в боля-меня вменяемом виде.
3. Классическая Java не имела инструментов для разработки под веб. Вообще. Сервлеты и прочие умные слова появились намного позже. Изначально руби в вебе мог быть возможен только в виде CGI, что есть ололо, но со временем всё изменилось. Название тут ни при чём, я ведь уже написал: Область применения выражается в наборе стандартных библиотек, а не в особенностях языка.
4. Эти люди ничем не хуже тех, кто пытается засунуть классы в JS.
под ассемблером, я имел в виду, естественно, язык, прямо переводящийся в бинарный код под PC. как-то мой опыт его использования не доходил до нахождения в нём ООП, под всяческие пролог- и смоллток-машины я не кодил.
если отойти от критерия динамичности языка (к которому в общем-то описанные автором различия никакого отношения не имеют), можно было и вовсе с С++ сравнить. на нём тоже можно сайты писать. И кстати,
> Изначально руби в вебе мог быть возможен только в виде CGI,
Изначально в PHP тоже. потому я не понимаю вашего критерия «предназначенности для веба».
если отойти от критерия динамичности языка (к которому в общем-то описанные автором различия никакого отношения не имеют), можно было и вовсе с С++ сравнить. на нём тоже можно сайты писать. И кстати,
> Изначально руби в вебе мог быть возможен только в виде CGI,
Изначально в PHP тоже. потому я не понимаю вашего критерия «предназначенности для веба».
PHP изначально был задуман как язык для парсинга HTML, в нём изначально заложен данный функционал, как то встраивание непосредственно в HTML, обширная библиотека для работы со строками и т.д. А в руби ничего не было. Пока спустя годы не написали. Ибо это general purpose язык для работы в первую очередь в консоли.
а вы можете менее голословно сказать, насколько позже самого создания языка в джаве и руби появилось встраивание непосредственно в HTML? по части библиотеки работы со строками аргумент не принимаю. в джаве и руби они тоже очень неплохи почти с рождения.
Мощная поддержка сервер-сайд разработки на Java появилась в 1999 году, сам язык появился в 1991, как я помню. J2EE — это целая платформа, нацеленная на корпоративные решения вокруг Java. Вот хорошая цитата: it adds libraries which provide functionality to deploy fault-tolerant, distributed, multi-tier Java software, based largely on modular components running on an application server.
Понимаете, веб — это не только отослать клиенту HTML. Это ещё управление сессиями, кукисами, хедерами, реагирование на входящие данные, обработка исключений совместимо с HTTP и т.д. и т.п. Когда у языка нет поддержки всего этого, то для веба он не предназначен. Ибо писать всё это руками — увольте!
Понимаете, веб — это не только отослать клиенту HTML. Это ещё управление сессиями, кукисами, хедерами, реагирование на входящие данные, обработка исключений совместимо с HTTP и т.д. и т.п. Когда у языка нет поддержки всего этого, то для веба он не предназначен. Ибо писать всё это руками — увольте!
PHP был задуман как язык для ПАРСИНГА HTML? Ну ты подумай… А я и не знал
Питон в этом плане похож на ЖС, чем на ПХП, что не мешает ему использоваться в backend.
если по-вашему никак, то давайте что ли ассемблер с php и javascript сразу будем сравнивать
Вы — передёргиваете. Асм и (пхп/жс) — языки разных уровней. А пхп и жс — похожи что по области применения, что по типизации, что по приведению типов, по способу компиляции и т.д.
и ещё раз, в чём схожесть применения ЖС и ПХП? пхп — бекэнд, жс — фронтенд, а node.js — не аргумент, почему — написал во втором пункте habrahabr.ru/blogs/webdev/122803/#comment_4021699
Не путайте тёплое с мягким, JS здесь пример того «как работают переменные», а не «что в них хранится» или «где они используются». В разрезе данного топика было бы корректно сравнивать что угодно, даже какой нибудь Фортран…
см. Node.js
> позволяют лично мне до сих пор получать удовольствие от написания программ на PHP, даже несмотря на его очевидные минусы, вроде несогласованности названий функций, не самый краткий синтаксис, весьма низкую производительность и др.
Вторая часть предложения (про минусы) вызывает недоумение при виде первой части (про удовольствие) ;)
Вторая часть предложения (про минусы) вызывает недоумение при виде первой части (про удовольствие) ;)
Ну вы же понимаете, что PHP вряд ли бы стал таким популярным, если бы у него эти недостатки ощущались бы столь серьёзно, что сильно перевешивали бы преимущества :)?
Он был популярен только по одной причине — LAMP + очень низкий порог вхождения (типа «пиши php-код прямо в HTML и не парься»), а не потому что на нем приятно писать ;)
Это был первый язык, который вывел работу со сроками и, соответственно, гипертекстом, на новый уровень удобства. Плата оказалась колоссальной, так как по сути это был шаблонизатор-переросток и типовая архитектура приложения на нем до недавнего времени была надругательством над архитектурами приложений как таковыми (тонны точек входа и выхода, смешение интерфейса и логики в одну кашу и т.д.), и только сейчас ситуация очень медленно возвращается в нормальное русло, но low-end интернет проекты будут болеть аморфностью еще очень долго.
по сути это был шаблонизатор-переросток
За это его и полюбили, и за это его любят и сейчас. Для сайтов класса «типовая визитка с гостевухой» такой подход очень даже подходит, и именно в стиле «всё в одну кашу». Попытки делать простые вещи сложными путями (с помощью всяких громких слов типа ООП/МVС) редко порождают что-то большее, чем просто большее количество уязвимостей…
Все это очень относительно, некоторые даже от программирования на коболе ощущают удовольствие :)
Вы вот любите семантику PHP, а вот меня она например просто бесит и я люблю семантику JavaScript, если для вас PHP лучше чем JavaScript то это не повод утверждать что PHP глобально лучше чем JavaScript.
Не, ну, JavaScript это никак не «большинство динамических языков».
Похожую семантику я своими глазами видел у питона и руби — вроде как это достаточно популярные «другие» динамические языки :)?
какую вы похожую семантику там видели? поясните, пожалуйста. не видел в них никакой похожей семантики.
Ну, да, возможно, я немного погорячился. Но, если я не ошибаюсь, и в питоне и в ruby переменные типа «хэш» и «массив» также передаются по ссылке, в то время, как в PHP эти же переменные передались бы по значению. Также, foreach() пробегается по копии — можно спокойно модифицировать массив, по которому идет foreach() и не напороться при этом на подводные грабли.
Как минимум то же самое прототипное наследование. Вообще языки на самом деле очень похожи (сущностью, но не синтаксисом)
где вы в пайтоне и руби нашли прототипное наследование?
Под капотом.
я почему-то так и подумал. принцип наследования у php, ruby и python очень схож, и к прототипности он не имеет никакого отношения. где капот?
А что есть «прототипность»?
прототипная объектная модель — это когда нет классов, а у всех объектов есть только некоторый прототип, который копируется при создании нового экземпляра. есть на википедии. основы javascript.
Основы javascript: прототип никуда не копируется.
И чем подобный прототип принципиально отличается от классов в питоне?
И чем подобный прототип принципиально отличается от классов в питоне?
копирование прототипа — обобщённый принцип прототипности. да, в javascript свойства заимствуются у прототипа, если отсутствуют у дитя.
чем это отличается от классов в питоне? а вы хотя бы понимаете, чем отличается объект от класса?
чем это отличается от классов в питоне? а вы хотя бы понимаете, чем отличается объект от класса?
Избавьтесь, пожалуйста, от оборотов «вы хотя бы понимаете».
В питоне класс — такой же объект, который можно использовать, как объект и динамически менять, как объект, с внесением изменений во все порождённые объекты (как с прототипами в JS).
В питоне класс — такой же объект, который можно использовать, как объект и динамически менять, как объект, с внесением изменений во все порождённые объекты (как с прототипами в JS).
нет, извините, не избавлю. ибо, видимо, не понимаете.
класс в питоне и руби хоть и объект, но от этого он классом быть не перестаёт.
главное принципиальное различие здесь в том, что класс описывает поведение объекта, зависящее от внутреннего состояния, а объект описывает это самое состояние. и вы не можете в питоне или руби задать модификацией класса-предка состояние объекта класса-потомка.
класс в питоне и руби хоть и объект, но от этого он классом быть не перестаёт.
главное принципиальное различие здесь в том, что класс описывает поведение объекта, зависящее от внутреннего состояния, а объект описывает это самое состояние. и вы не можете в питоне или руби задать модификацией класса-предка состояние объекта класса-потомка.
Каким образом вы можете произвести данную модификацию в прототипной модели? Как в «обощённом» варианте, так и в JS?
function Table(table_legs_num) { this.table_legs = table_legs.num; }
t = new Table(5);
function SquareTable() {}
SquareTable.prototype = t;
t1 = new SquareTable();
alert(t1.table_legs);
t.table_legs = 3;
alert(t1.table_legs);
Вы так спешили, что опечатались: this.table_legs = table_legs_num
Это работает только в JS-версии, но не в «обобщённой».
Ну и тоже самое на питоне:
Это работает только в JS-версии, но не в «обобщённой».
Ну и тоже самое на питоне:
class One: X = 1; class Two (One): pass obj = Two() print(obj.X); // 1 One.X = 2; print(obj.X); // 2
да, опечатался. впрочем, должен признать, вы тоже, комментарии в питоне #.
и да, здесь признаю свою неправоту, давно за питон не садился.
однако, попробуйте сделать так в руби.
и да, здесь признаю свою неправоту, давно за питон не садился.
однако, попробуйте сделать так в руби.
и вообще, в питоне хотя бы прототип у объекта менять нельзя. ну и смысловая нагрузка класс <-> объект сохраняется.
Руби никогда не использовал.
Я просто хотел сказать, что на мой взгляд каких-то фундаментальных различий тут нет.
Давайте оставим это :)
Я просто хотел сказать, что на мой взгляд каких-то фундаментальных различий тут нет.
Давайте оставим это :)
Тривиально, не понял соли…
class One
def x; 1; end
end
class Two < One; end
obj = Two.new
puts obj.x # 1
One.class_eval { def x; 2; end }
puts obj.x # 2
За другие языки не скажу, но у JS и Python гораздо больше общего чем с PHP.
А кто мешает в PHP передавать переменные по ссылке? Может всё дело просто в незнании?
Обратите внимание на & в объявлении функции.
<?php
$arr = array(
'key1' => 'value1',
'key2' => 'value2',
);
function doSmthWithArray(&$arr) {
$arr['key3'] = 'value3';
}
doSmthWithArray($arr);
print_r($arr); // выводит Array ( [key1] => value1 [key2] => value2 [key3] => value3 )
?>
Обратите внимание на & в объявлении функции.
Этот пример приводился в оригинальной статье. Дело не в этом, а что без лишних телодвижений переменная копируется, тогда как в том же JS она передаётся по ссылке.
«лишних телодвижений»? Добавить один символ для Вас — это лишние телодвижения? Есть варианты как это реализовать более удобно? По-моему удобнее некуда, и можно сколько угодно ругать язык, но конкретно этот пример говорит только о его гибкости, и ни о чём другом.
Переменные ВСЕГДА И ВЕЗДЕ копируются!
Что-то заключило…
var x = 5
function zzz(y) {
y = 10
}
alert('x: ' + x)
zzz(x)
alert('x: ' + x)
Объекты в JS передаются по ссылке, копируются (передаются по значению) лишь простые типы.
И в PHP также, удивительно, да?
Единственное отличие, о чём так радуется ТС — массивы в php исторически считаются простыми типами и потому — копируются, а в JS — передаются по ссылке.
Угу. Но учитывая процедурное прошлое и связь с С это не должно быть странным, а вполне естественная вещь.
В C массив == ссылка.
Ну значит в паскале когда-то так было, я уже и забыл.
Вы, похоже, не поняли смысла статьи :). В PHP, безусловно, можно передавать значения по ссылке, но делать это необязательно, и тогда будет создана копия. И мне кажется это удобным.
Поправка — копия будет сделана только тогда, когда вы попытаетесь что-то записать в эту самую переменную, т.к. в PHP работает Copy-On-Write.
Я говорю о том, что в языке реализованы оба подхода, и сложность их реализации внутри самого скрипта одинакова. Всё зависит от привычки конкретно взятого программиста: если человек долгое время писал, скажем, на python и привык передавать переменные по ссылке, то никто ему не мешает написать абсолюнто весь скрипт на php в таком-же ключе.
Угу. А вот только если человек привык, что всё копируется, то что на JS или Python придется делать :)? Правильно, на JS использовать jQuery, насчёт Python не знаю, я думаю, там тоже есть костыли для того, чтобы реализовать передачу по значению. Но это всё будут костыли, а не встроенная функциональность. И речь именно об этом.
«Большинство динамических языков» и JavaScript – это совсем не одно и то же. Например, слабая динамическая типизация (как в JS и PHP) среди популярных языков встречается ещё, разве что, в Perl. А в Python, Ruby, Scheme, Common Lisp, Lua, Clojure, Groovy она строгая. Подобных различий можно найти много, поэтому использовать JS в качестве «эталона», мягко говоря, некорректно. Я бы посоветовал изменить название топика не более соответствующее содержанию.
Ну, да, я пожалуй всё-таки немного погорячился, обобщив все динамические языки :). Я согласен, что многие моменты слишком существенно отличаются, чтобы можно было давать такой заголовок.
У Lua строже, чем PHP, но мягче питона или руби. Можно и настроить (через dubug.setmetatable()) — будет почти один в один, как у PHP.
Основная проблема PHP не в самом языке, а в очень неконсистентной стандартной библиотеки.
Чего только стоят функции, принимающие аргументы в любом порядке…
Чего только стоят функции, принимающие аргументы в любом порядке…
Интересная статья и интересное сравнение, для полноты сравнения возможно нужно было сравнить 3 языка, это было бы увлекательнее(имхо).
по поводу замыканий на JS, их несложно сделать вот так:
Не так читаемо как «use», конечно, но типа явное замыкание.
for(var i = 0; i < 10; i++) funcs.push( function(i) { return function() { return i; } }(i) );
Не так читаемо как «use», конечно, но типа явное замыкание.
Тут тоже есть подводный камень:
Если условный «i» — объект, то он передастся по ссылке и фокус не пройдет.
var i={"c":undefined};
var funcs=[];
for (var c =0; c<10; ++c){
i.c=c;
funcs.push( function(i) { return function() { return i.c; } }(i) );
}
for (var c =0; c<10; ++c){ console.log(funcs[c]()) }
Если условный «i» — объект, то он передастся по ссылке и фокус не пройдет.
А в PHP разве не так?
Попробовал и так и эдак:
так что снова таки совсем большой разницы с JS не вижу.
Или можно как-то заставить «глубоко замкнуть» с помощью «use»?
Попробовал и так и эдак:
class test { };
$i = new test();
for($c = 0; $c < 10; $c++) { $i->c = $c;$funcs[] = function() use($i) { return $i->c; }; };
foreach($funcs as $func) echo $func().",";
$funcs = array();
$i = new test();
for($c = 0; $c < 10; $c++) { $i->c = $c;$funcs[] = function() use(&$i) { return $i->c; }; };
foreach($funcs as $func) echo $func().",";
так что снова таки совсем большой разницы с JS не вижу.
Или можно как-то заставить «глубоко замкнуть» с помощью «use»?
Это было не в тему о различиях, а как предостережение новичкам в js.
Про «большую разницу», имхо, замыкания в php «слизаны» с C++0x, которые в свою очередь стремились сделать конструкцию, идейно напоминающую как раз это:
Повторюсь, это чисто субъективное мнение.
Про «большую разницу», имхо, замыкания в php «слизаны» с C++0x, которые в свою очередь стремились сделать конструкцию, идейно напоминающую как раз это:
function(i) { return function() { return i.c; } }(i)
Повторюсь, это чисто субъективное мнение.
Простите меня, но надо чуть больше серьёзности, имхо.
Автор, расскажите откуда вы взяли инфу об изменяемых сроках?
Да можно даже тупо эксперимент поставить: измерьте время исполнения следующего кода на PHP:
А потом того же кода на языках с неизменяемыми строками. И вы сразу увидите разницу, ибо у PHP получается линейный график от количества итераций, а такое возможно только когда строки изменяемые. ЧТД
<?php
$var = '';
for($i = 0; $i < 100000; $i++) $var .= 'megalongstr111';
А потом того же кода на языках с неизменяемыми строками. И вы сразу увидите разницу, ибо у PHP получается линейный график от количества итераций, а такое возможно только когда строки изменяемые. ЧТД
В Chrome V8 этот кусок очень оптимизирован. Там, внутри, работает аналог StringBuilder'a. Так что, например, в Хроме — вы будете удивлены.
Да, это круто, что этот кусок оптимизирован. Но вроде как даже просто так поменять один символ в JS строке уже нельзя, если я не ошибаюсь? Так что всё равно immutable природа строк в JS изо всех щелей прёт :)
immutable-строки есть добро :) кстати, и в JVM/.NET так же, и на некоторых иных платформах.
Кстати, обычно для конкатенации и других модификаций я просто пользуюсь массивами. Обычно нет нужны работать на уровне символов, чаще всего приходится оперировать словами, предложениями, либо просто заменять исходную строку другой (regexps etc.).
Если применить здравый смысл и исходить из того, что разработчики ECMAScript не лыком шиты. То можно сделать нехитрые выводы:
1. Если такой фичи нет — значит она не нужна
2. Если вы собираетесь менять символ в строке — вы делаете что-то не так. String !== Array у них разные представления данных соответствено то, что они имеют «общие методы» — это совпадение.
Честно говоря я ни разу не задумывался о том, чтобы заменить символ в JavaScript строке(это даже как-то дико), хотя это так или иначе можно сделать:
Прочитал «Отличие Javascript от PHP» как каламбур из серии «Чем отличается А от Б?». Ждем от вас «Отличие Haskell от PHP», «Отличие SQL от PHP», «Отличие Иврита от PHP». Из вашего профиля я узнал, что вы пишете всякую ерунду :), позволю процитировать графу о себе:
1. Если такой фичи нет — значит она не нужна
2. Если вы собираетесь менять символ в строке — вы делаете что-то не так. String !== Array у них разные представления данных соответствено то, что они имеют «общие методы» — это совпадение.
Честно говоря я ни разу не задумывался о том, чтобы заменить символ в JavaScript строке(это даже как-то дико), хотя это так или иначе можно сделать:
String.prototype.change = function (index, value) {
return this.slice(0, index) + value + this.slice(index + 1);
};
var a = '01234';
a = a.change(0, 'Z'); // "Z1234"
a; // "Z1234"
Прочитал «Отличие Javascript от PHP» как каламбур из серии «Чем отличается А от Б?». Ждем от вас «Отличие Haskell от PHP», «Отличие SQL от PHP», «Отличие Иврита от PHP». Из вашего профиля я узнал, что вы пишете всякую ерунду :), позволю процитировать графу о себе:
Пишу всякую ерунду. В основном на PHP, иногда также на русском языкеЖелаю вам не писать ерунды и глубже подойти к изучению JavaScript — судя по вашей статье вы его совсем знаете. Если был резок в своих высказываниях — прошу простить, задели вы меня своей статьёй.
Ждем от вас «Отличие Haskell от PHP», «Отличие SQL от PHP», «Отличие Иврита от PHP».
А также — отличие огурцов от PHP
Аргумент "… исходить из того, что разработчики ECMAScript не лыком шиты.." просто убивает…
Безотносительно контекста, «Если такой фичи нет — значит она не нужна» — это бред.
Безотносительно контекста, «Если такой фичи нет — значит она не нужна» — это бред.
Вполне разумный аргумент, намекающий на то, что разработчики языка заботятся о тех, кто будет на нем писать. ECMAScript сейчас бурно развиваются, в нем появляются новые фичи, которые действительно нужны, а не так чтобы «вот в PHP можно заменить символ строки, а в JavaScript нельзя — дайте!!!11». Ещё раз «Такой фичи нет — значит она не нужна». Я имею большой опыт разработки на JavaScript и ещё ни разу не сталкивался с проблемой замены N-го символа в строке, поэтому я не удивлен отсутствием такого функционала.
Как-то я категорично. Смягчу фразу «Такой фичи нет — значит она не нужна повсеместно». В 99% случаев не нужна, поэтому и не включили в «Ядро». Единственное место, где замена символа с строке сократила бы код — это capitalize:
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
Но ради одного такого «бонуса» придется отказаться от обратной совместимости (сейчас действует политика совместимости со старыми версиями).Поясню чтобы не путать читающих. Вот это
Ещё:
Т.е. свое состояние примитив не может изменять, поэтому
'pewpew'[0] = 'P'
невозможно без кардинальных изменений в всем JavaScript. Потому, что строка в JavaScript — примитивный тип и то, что у строки можно вызывать методы на самом деле «магия» интерпретатора, который делает следующее:// Ваш код
var a = 'abc';
var b = a.toUpperCase();
console.log(a, b); // "abc", "ABC"
// Интерпретатор понимает его как
var a = 'abc';
// Создает временный объект. Метод toUpperCase вызывается у временного объекта.
var temp_a = new String(a);
var b = temp_a.toUpperCase();
free(temp_a); // такой функции нет, она для примера
console.log(a, b); // "abc", "ABC"
Ещё:
// Ваш код
var a = 'abc';
a[0] = 'A';
console.log(a); // "abc"
// Интерпретатор понимает его как
var a = 'abc';
// Создает временный объект. Переменная [0] создается у временного объекта
var temp_a = new String(a);
temp_a[0] = 'A';
free(temp_a); // такой функции нет, она для примера
console.log(a); // "abc"
Т.е. свое состояние примитив не может изменять, поэтому
'pewpew'[0] = 'P'
невозможно без кардинальных изменений.Я даже соглашусь с тезисом о том, что конкретно эта фича в рассматриваемом контексте не нужна. Мне претила аргументация.
[[ на правах пародии ]]
[[ на правах пародии ]]
Если применить здравый смысл и исходить из того, что разработчики PHP не лыком шиты. То можно сделать нехитрые выводы:
1. Если такая фича есть — значит она нужна
2. Если вы собираетесь менять символ в строке — это нормально. Строка по сути представляет собой C-подобный фиксированный массив и мы можем обращаться к её копонентам как в роли R-value, так и L-value.
Итераторов нормальных нет, значений аргументов по умолчанию нет, связи функции с контекстом нет и ещё кучи всего нет, но разработчикам виднее
Да, им (Opera, MS, Mozilla, Apple, ...) виднее на то они и разработчики :) Все это будет: Iterators, Generators, Reflection, More.... Скоро будет в стандарте, потом на серверном JavaScript, потом все вендоры прикрутят и будет везде. C JavaScript не все так быстро, думаю, вы понимаете причины. Москва не сразу строилась ©
Что не нравится в обоих упомянутых ЯП, так это то, что массив=хэш.
Имхо очень плохое архитектурное решение. Логически это должны быть две совершенно разные сущности.
Отсюда и чудовищная неэффективность: david-m.livejournal.com/1117497.html
Но это еще полбеды. Куда хуже — нестрогость типизации, а именно автоматическая конвертация типов. Это может быть удобно для маленьких скриптов, но ужасно в масштабах больших фреймворков.
JS ужасен своей объектной моделью (натурально, если б она была нормальная, неужто кто-то стал бы плодить сотни механизмов OOP на JS?), кто дебажил, тот понимает (это когда в FireBug смотришь на панель Watch и все объекты предстают перед тобой как hashmap, при этом совершенно непонятно каковы классы каждого объекта).
Имхо очень плохое архитектурное решение. Логически это должны быть две совершенно разные сущности.
Отсюда и чудовищная неэффективность: david-m.livejournal.com/1117497.html
Но это еще полбеды. Куда хуже — нестрогость типизации, а именно автоматическая конвертация типов. Это может быть удобно для маленьких скриптов, но ужасно в масштабах больших фреймворков.
JS ужасен своей объектной моделью (натурально, если б она была нормальная, неужто кто-то стал бы плодить сотни механизмов OOP на JS?), кто дебажил, тот понимает (это когда в FireBug смотришь на панель Watch и все объекты предстают перед тобой как hashmap, при этом совершенно непонятно каковы классы каждого объекта).
Тут, в основном, критикуют, но позвольте мне выразить благодарность за статью и, конечно, комментарии! У меня слабо с матчастью, но порой такие отрывочные, но емкие знания — это то, чего не хватает, чтобы собрать свой опыт в единую картину ради более ясного понимания.
некоторые такие отрывочные знания очень вредят пониманию сути языка новичками, что приводит к появлению сотен «программистов на jQuery» и плохой репутации PHP.
количество ключей в асоцивтивном масиве? Да пожалуйсто.
но вообщето странно cравнивать асоциативные масивы в php и обьекты в js
function count(arr){ return Object.keys(arr).length}
но вообщето странно cравнивать асоциативные масивы в php и обьекты в js
мне думается, что в первую очередь все зависит от уровня разработчика
а так получается спор не о чем
а так получается спор не о чем
Sign up to leave a comment.
Отличие Javascript от PHP