> в котором массивы javascript уделывают ваши php-шные по ряду позиций
Из 1.7 — Array comprehensions, например (в Python'e также используется):
var odds = [k for each (k in range(0, 11)) if (k % 2 == 0)];
> ваши php-шные
Какие они «ваши»? Вы написали PHP? Или может принимали хоть какое-нибудь мало-мальское участие? Или может быть Вы вообще стоите у истоков и были идеологическим создателем PHP и его смешанных массиво-хэшей? Вот те, кто это придумывал — те могут использовать подобные фразы ;) А тут, повторю, — изучайте языки, смотрите на их идеологии, сравнивайте, анализируйте, улавливайте общие и расходящиеся закономерности, на их основе — можете сами написать недостающие части.
a = {:a => 10}
b => {a => 20} # будет {{:a=>10}=>20}
> и скорее всего оно и к лучшему
почему же? строка (в объектной системе) — тоже объект. Вообще, к лучше или нет — спорный вопрос — возможно, когда только появлялись ассоциативные массивы, тоже были споры — «зачем оно надо? — цифровых индексов не хватает что ли?»
> товарищи, читаем документацию, тогда и удивляться не придется
Уж, поверьте, читали. Повторю — подобных «незначительных» оговорок — предостаточно. Но основная идея — это выяснить причину, а не просто принять факт — «нуу, нам так сказали… не знаем». А ответ прост — это побочные эффекты, являющиеся расплатой за создание «более удобных вещей» (более усилинных абстракций).
Да там куча таких оговорок (все не упомнишь). И сам факт — не суть важен, важна причина — почему это так случилось. Если это осознано, то это плата за размытие рамок между массиов численным и ассоциативным и созданием единой абстракции.
> т.к. я не знаю можно ли переопределить оператор []
нельзя
Сейчас смотрю исходники array'я в PHP (расположены в /ext/standard/array.c), и в частности описание функции array_shift / array_unshift — там хэши используются всегда (нет такого понятия, как просто массив, — всегда его роль играет хэш; собственно, в самом PHP тоже отдельного понятия хэш нет). Хотя, я простотрел бегло, и 100% не могу утверждать.
Относительно, это хорошо. Так они ушли от разделения абстракции с численной адресацией и нечисленной (и не важно, что на низком уровне изспользуется лишь численные смещения в памяти). Описывая словестно, мы же можем говорить — «хранилище с парами ключ — значение», — а что при этом является ключом (цифры, буквы, объекты) — не суть важно.
В любом случае, в PHP Вы используете wrapper-функции (типа array_shift), которые внутри себя анализируют текущий объект и, в зависимости от его типа, применяют разные подходы для получения одинакового результата на выходе. Ну так напишите тоже такой wrapper.
Действительно, в PHP в плане массивов сделали более общую абстракцию (за счет глобальных функции-wrapper'ов), — я думаю, это хорошо, в JS же — это методы (но Вам ничего не мешает сделать wrapper'ы).
Кстати, в Ruby, такая же реализация:
a = []
a[10] = 1;
a.lenght # 11
Python в данном случае заругается (индекс «10» не найден).
а смысл? что за подход вообще? просто — изучайте языки, смотрите, где и какие реализации (идеологические) используются; что-то не нравится — напишите (допишите) свое — Вы же программист.
В ключах, в ключах, просто человек решил сделать небольшой хак — использовать в качестве интересующих значений — ключи. Т.е. {'string1': true, 'bla': true}. Однако, это очень шатко — так, если, будет строка, 'toString', то «пустой» хэш вернут true:
Конечно, все зависит от реализаций, но даже в теории:
— .search(...) использует RegExp, поэтому будет медленнее (+ еще на join() время тратится);
— оператор in использует гараздо меньшее количество действий, которые еще и выполняются быстрее.
> так питон-то «нативно» поддерживает классы, без оберток )
=) замените слово «class» из Питона на «function» в JS — практически не найдете отличий
> но все же очень хотелось бы посмотреть более-менее сложный проект с серьезным применением прототипов без костылей
можно порыться в .js-файлах firefox'a или thunderbird'a, которые с XUL'ом и XPConnect'ом общаются (там, конечно, тоже не прелесть, но — как пример — можете посмотреть, как там используются прототипы)
> вобщем, ладно, все, а то что-то не в то русло пошло ))
спасибо за интересную дискуссию =)
о, пардон, если показался слишком навязчивым =) и Вам спасибо )
а && в PHP можно использовать для одиночных присвоений (кстати, удобно, когда надо что-то приплюсовать к элементу массива по одиночному условию), больше в этом ключе — не надо; в нотации из JS — в PHP это работать не будет
Ы )) минусанул новичок (и я знаю причину — эта запись с && несколько отличается от той, которую он видел в книжке «PHP для чайников» — и хрен ты бы с этим, да только я не пропагандировал, а показал возможность языка)
> скорость разработки, лаконичность и «человечность» кода, легкость поддержки.
все это пытаются делать в обертках (типа jQuery, Prototype и т.д.), естественно, жертвуя производительностью в ресурсах
> скорость разработки, лаконичность и «человечность» кода, легкость поддержки.
а можно и без фреймворков (насчет последних трех пунктов — точно), а вот насчет скорости разработки — смотря, что разрабатывается
> мне очень нравится питон
ну и JS, значит, тоже должен ;) поскольку, идеи общие
> идея того, что любой объект автономен и полностью изменяем. эта идея сама по себе очень проста.
однако, опять же, мне видится это overkill'ом из-за слишком большой свободы.
так в Python'e тоже самое (все объекты динамические и автономные):
class A(object):
def __init__(self, a=10):
self.a = a
def test(self):
print self.a
a = A(20)
a.a # 20
del a.a
a.a # None
a.a = 10
a.test() #10
a.b = 20 #20 (собственное свойство)
b = A()
b.a #10 (по умолчанию из конструктора)
a.__class__.c = 30 # расширили класс новым свойство
a.c # 30 оно доступно (посредством делегирования) во всех порожденных инстансах
b.c # тоже 30
a.c = 40 # перезаписали, свойство "с" теперь свое
a.c # 40
b.c # 30 - делегация
del a.c
a.c # 30 снова делегация
del A # удаляем ссылку на объект-класс
b.__class__.d = 50 # но все еще можем расширять объект-класс через инстансы
a.d # 50
b.d # 50
Ага =) это вообще, дикая смесь какая-то. Я бегло тогда читал overview-es4, — с виду показалось перегруженным, лишние конструкции. Написано, что все еще так же можно использовать function A() {} и ее прототип для порождения инстансов (как альтернатива class A).
Тоже нет, — если объявлен метод в предке, то объявление прототипного метода с таким же именем в потомке — ничего не даст (будет использован метод из предка, поскольку это this-свойство и оно найдется сразу).
The . operator produces a function (more specifically, a closure) that is already dispatched and has this bound to the left operand of the. operator.
dynamic class A {
function test1() {}
prototype function test2() {}
}
dynamic class B extends A {
function test3() {}
prototype function test4() {}
}
var a = new B();
var b = new B();
a.test1 === b.test1 // false
b.test2 === b.test2 //true
a.test3 === b.test3 // false
a.test4 === b.test4 // true
B.method === A.method, где A — базовый класс, а B — наследник? Я не знаю, как достучаться до такой конструкции (через класс, в смысле — скачай ES4 — посмотри, я его внутренности не знаю)
Порожденные же инстансы, будут выдавать false на ===, если метод описан в прототип — true =) Вот тоже — что это за смесь такая (идиотская, а может и нет) — класс ввели — но тут же рядом — прототипы =)
Из 1.7 — Array comprehensions, например (в Python'e также используется):
> ваши php-шные
Какие они «ваши»? Вы написали PHP? Или может принимали хоть какое-нибудь мало-мальское участие? Или может быть Вы вообще стоите у истоков и были идеологическим создателем PHP и его смешанных массиво-хэшей? Вот те, кто это придумывал — те могут использовать подобные фразы ;) А тут, повторю, — изучайте языки, смотрите на их идеологии, сравнивайте, анализируйте, улавливайте общие и расходящиеся закономерности, на их основе — можете сами написать недостающие части.
я в курсе; я говорил в теории
Хотя, например, в Ruby, могут:
a = {:a => 10} b => {a => 20} # будет {{:a=>10}=>20}> и скорее всего оно и к лучшему
почему же? строка (в объектной системе) — тоже объект. Вообще, к лучше или нет — спорный вопрос — возможно, когда только появлялись ассоциативные массивы, тоже были споры — «зачем оно надо? — цифровых индексов не хватает что ли?»
Уж, поверьте, читали. Повторю — подобных «незначительных» оговорок — предостаточно. Но основная идея — это выяснить причину, а не просто принять факт — «нуу, нам так сказали… не знаем». А ответ прост — это побочные эффекты, являющиеся расплатой за создание «более удобных вещей» (более усилинных абстракций).
нельзя
Сейчас смотрю исходники array'я в PHP (расположены в /ext/standard/array.c), и в частности описание функции array_shift / array_unshift — там хэши используются всегда (нет такого понятия, как просто массив, — всегда его роль играет хэш; собственно, в самом PHP тоже отдельного понятия хэш нет). Хотя, я простотрел бегло, и 100% не могу утверждать.
Относительно, это хорошо. Так они ушли от разделения абстракции с численной адресацией и нечисленной (и не важно, что на низком уровне изспользуется лишь численные смещения в памяти). Описывая словестно, мы же можем говорить — «хранилище с парами ключ — значение», — а что при этом является ключом (цифры, буквы, объекты) — не суть важно.
Действительно, в PHP в плане массивов сделали более общую абстракцию (за счет глобальных функции-wrapper'ов), — я думаю, это хорошо, в JS же — это методы (но Вам ничего не мешает сделать wrapper'ы).
Кстати, в Ruby, такая же реализация:
Python в данном случае заругается (индекс «10» не найден).
Да и, в PHP не все так гладко:
> убедите же меня
а смысл? что за подход вообще? просто — изучайте языки, смотрите, где и какие реализации (идеологические) используются; что-то не нравится — напишите (допишите) свое — Вы же программист.
да ну в статье не об этом речь шла =) А где удобная?
«key in obj» анализирует вхождение ключа, значение ключа (в отличии от «obj.key») его не инстересует
В Gecko тоже, правда, на уровне Си-кода (см array_indexOfHelper(...)):
hg.mozilla.org/mozilla-central/file/3ed5ca9b8277/js/src/jsarray.cpp
> А варианты поиска без перебора следующие:
В принципе, все они внутри себя перебор используют.
alert('toString' in {}); // true— .search(...) использует RegExp, поэтому будет медленнее (+ еще на join() время тратится);
— оператор in использует гараздо меньшее количество действий, которые еще и выполняются быстрее.
Однако, оператор «in» также анализирует прототип конструктора (при обращении к [[HasProperty]]):
var a = {}; a.__proto__.test = 'bla'; alert('test' in a); // true=) замените слово «class» из Питона на «function» в JS — практически не найдете отличий
> но все же очень хотелось бы посмотреть более-менее сложный проект с серьезным применением прототипов без костылей
можно порыться в .js-файлах firefox'a или thunderbird'a, которые с XUL'ом и XPConnect'ом общаются (там, конечно, тоже не прелесть, но — как пример — можете посмотреть, как там используются прототипы)
> вобщем, ладно, все, а то что-то не в то русло пошло ))
спасибо за интересную дискуссию =)
о, пардон, если показался слишком навязчивым =) и Вам спасибо )
Благодарю.
все это пытаются делать в обертках (типа jQuery, Prototype и т.д.), естественно, жертвуя производительностью в ресурсах
> скорость разработки, лаконичность и «человечность» кода, легкость поддержки.
а можно и без фреймворков (насчет последних трех пунктов — точно), а вот насчет скорости разработки — смотря, что разрабатывается
> мне очень нравится питон
ну и JS, значит, тоже должен ;) поскольку, идеи общие
> идея того, что любой объект автономен и полностью изменяем. эта идея сама по себе очень проста.
однако, опять же, мне видится это overkill'ом из-за слишком большой свободы.
так в Python'e тоже самое (все объекты динамические и автономные):
class A(object): def __init__(self, a=10): self.a = a def test(self): print self.a a = A(20) a.a # 20 del a.a a.a # None a.a = 10 a.test() #10 a.b = 20 #20 (собственное свойство) b = A() b.a #10 (по умолчанию из конструктора) a.__class__.c = 30 # расширили класс новым свойство a.c # 30 оно доступно (посредством делегирования) во всех порожденных инстансах b.c # тоже 30 a.c = 40 # перезаписали, свойство "с" теперь свое a.c # 40 b.c # 30 - делегация del a.c a.c # 30 снова делегация del A # удаляем ссылку на объект-класс b.__class__.d = 50 # но все еще можем расширять объект-класс через инстансы a.d # 50 b.d # 50docs.huihoo.com/web/js/es4/core/classes.html
dynamic class A { function test1() {} prototype function test2() {} } dynamic class B extends A { function test3() {} prototype function test4() {} } var a = new B(); var b = new B(); a.test1 === b.test1 // false b.test2 === b.test2 //true a.test3 === b.test3 // false a.test4 === b.test4 // trueB.method === A.method, где A — базовый класс, а B — наследник? Я не знаю, как достучаться до такой конструкции (через класс, в смысле — скачай ES4 — посмотри, я его внутренности не знаю)
Порожденные же инстансы, будут выдавать false на ===, если метод описан в прототип — true =) Вот тоже — что это за смесь такая (идиотская, а может и нет) — класс ввели — но тут же рядом — прототипы =)