Обновить
2
0
Dmitry Soshnikov @dsCode

Пользователь

Отправить сообщение
> в котором массивы 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 и его смешанных массиво-хэшей? Вот те, кто это придумывал — те могут использовать подобные фразы ;) А тут, повторю, — изучайте языки, смотрите на их идеологии, сравнивайте, анализируйте, улавливайте общие и расходящиеся закономерности, на их основе — можете сами написать недостающие части.
> Ну, объекты в 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-функции (типа array_shift), которые внутри себя анализируют текущий объект и, в зависимости от его типа, применяют разные подходы для получения одинакового результата на выходе. Ну так напишите тоже такой wrapper.

Действительно, в PHP в плане массивов сделали более общую абстракцию (за счет глобальных функции-wrapper'ов), — я думаю, это хорошо, в JS же — это методы (но Вам ничего не мешает сделать wrapper'ы).

Кстати, в Ruby, такая же реализация:

a = []
 a[10] = 1;
a.lenght # 11


Python в данном случае заругается (индекс «10» не найден).

Да и, в PHP не все так гладко:

$a = array();
$a[10] = 1;
print_r($a); // aray [10] => 1
array_unshift($a, 20, 30);
print_r($a); // array [0] => 20, [1] => 30, [2] => 1 - почему индекс 10 стал 2?


> убедите же меня

а смысл? что за подход вообще? просто — изучайте языки, смотрите, где и какие реализации (идеологические) используются; что-то не нравится — напишите (допишите) свое — Вы же программист.
> «мучения javascript-программистов из-за неудобной реализации ассоциативных и простых массивов».

да ну в статье не об этом речь шла =) А где удобная?
> in применять безопаснее

«key in obj» анализирует вхождение ключа, значение ключа (в отличии от «obj.key») его не инстересует
> Для IE данный метод реализовывается с помощью перебора массива в цикле.

В Gecko тоже, правда, на уровне Си-кода (см array_indexOfHelper(...)):

hg.mozilla.org/mozilla-central/file/3ed5ca9b8277/js/src/jsarray.cpp

> А варианты поиска без перебора следующие:

В принципе, все они внутри себя перебор используют.
В ключах, в ключах, просто человек решил сделать небольшой хак — использовать в качестве интересующих значений — ключи. Т.е. {'string1': true, 'bla': true}. Однако, это очень шатко — так, если, будет строка, 'toString', то «пустой» хэш вернут true:

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'ом общаются (там, конечно, тоже не прелесть, но — как пример — можете посмотреть, как там используются прототипы)

> вобщем, ладно, все, а то что-то не в то русло пошло ))
спасибо за интересную дискуссию =)

о, пардон, если показался слишком навязчивым =) и Вам спасибо )
а && в 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.

docs.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 // true
ну, если абстрактно, — то да
В смысле — проверить, что

B.method === A.method, где A — базовый класс, а B — наследник? Я не знаю, как достучаться до такой конструкции (через класс, в смысле — скачай ES4 — посмотри, я его внутренности не знаю)

Порожденные же инстансы, будут выдавать false на ===, если метод описан в прототип — true =) Вот тоже — что это за смесь такая (идиотская, а может и нет) — класс ввели — но тут же рядом — прототипы =)

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность