Расширение прототипов встроенных обьектов: хорошо или плохо?
Неоднократно слышал от уважаемых мною людей, что Prototype.js — некошерно, потому что изменяет прототипы встроенных обьектов.
Недавно почитал про MooTools, и оказалось, что они тоже используют этот подход, более того, предоставляют удобный интерфейс для расширения прототипов. И у меня закрались сомнения. Действительно ли плохо менять встроенные прототипы? Чем это плохо, кроме того, что возможно, при подключении еще одного фреймворка, возникнут конфликты? Какие подводные камни? |
Цитата:
По теме: юзаю активно. |
Цитата:
Цитата:
Спасибо. |
Цитата:
Цитата:
|
Kolyaj, удалить? а если уже полмегабайта скриптов написано с расчетом на этот фреймворк?
|
Ну удалить можно, разумеется, только на начальном этапе. Вообще, если ты пишешь с использованием фреймворка, то ты должен писать в стиле этого фреймворка, иначе всегда будут находится концептуальные проблемы.
Проблемы с расширением прототипов могут возникнуть только если ты решил переопределить метод, уже определенный фреймворком, а это и есть написание кода вразрез используемому фреймворку. |
Kolyaj, это-то очевидно.
|
А какие еще могут возникнуть проблемы?
|
hogart, пока нельзя задавать внутреннее свойство {DontEnum} добавляемым методам/свойствам, не советуют расширять Object.prototype и Array.prototype. Причина: оператор in найдёт эти свойства в "пустых" объектах. В остальном - это в идеологии языка, поэтому - смело можно расширять всё, что захочется.
|
Цитата:
|
А вот мне кажется, что расширение прототипов встроенных объектов только вводит путаницу в код.
|
Цитата:
Цитата:
|
Ну тут сначала нужно разделить случаи. Первый -- это нивелирование различий браузеров: тот же forEach (да и остальные методы, кроме reduce-reduceRight) везде есть, в ИЕ нет. Второй случай -- добавление своих методов. Тут я тоже не вижу путаницы. Простой и полезный метод last, например,
var lastElem = getMyArray().last();Где тут путаница? Вот если бы вопрос стоял "Расширять ли прототипы во фреймворках?", тогда можно подумать, но в каждом случае отдельно, в зависимости от его целей и задач. |
Kolyaj,
Я бы реализовал функцию last(), а не метод в прототипе. Чтобы у других программистов не возникало вопросов при просмотре, например, такого кода: var myArray = ["some", "thing", "here"]; doSomething(myArray.last()) Тут может быть непрозрачно, откуда взялся этот ласт. Но пример утрирован, конечно. Может я и не прав, но думаю, что нужно локализовать свой код так, чтоб он не трогал глобальную область видимости и прототипы встроенных объектов (что тоже, по сути, глобально). |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Kolyaj, я, вроде бы, тоже. Но не хочется опираться только на собственную самоуверенность в таком достаточно фундаментальном вопросе:)
|
Цитата:
|
Zeroglif, да, конечно, расширять, я неверно выразился.
Цитата:
Цитата:
|
В общем, как всегда на этом форуме, — получил кучу очевидных ответов и туманных общих замечаний, и ничего нового. Печально, господа.
Неужели мы тут только для того, чтобы высокомерно отвечать новичкам, которые не то что JS, русского языка-то не знают? |
hogart, почему туманных? Здесь были и конкретные ответы/советы. Можно ещё раз:
Цитата:
Цитата:
- конфликт имён (подключение нескольких библиотек, но здесь - не важно - в прототипе описано или нет - в двух фреймворках может быть и две глобальные переменные, как, например, $); - в идеале, нужна документация для других программистов; - расширять Object.prototype не следует; - расширять Array.prototype можно, но тогда будет ограничение на итерацию по массивам через for ... in (либо, использовать в паре с .hasOwnProperty, либо "индексный" цикл (for var k = 0; k < .. ; k++), либо методы типа .forEach). Что смущает? |
Dmitry A. Soshnikov, ага, вот это уже лучше. Давайте обсудим.
Цитата:
Но, например, Python — тоже динамический язык, и в нем точно так же можно дополнять/менять поведение встроенных типов, но там это считается дурным тоном — и есть типы, аналогичные встроенным, но предназначенные для наследования/переопределения. Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
И опять таки — расширение встроенных классов запрещено на уровне языка. Хотя большинство питонистов все-таки более сознательны, чем люди, приходящие в JS. Цитата:
Цитата:
|
hogart,
Я, например, не вижу задач, которые бы рационально было решать с помощью расширения прототипов встроенных объектов. Ну, возможно, кроме маленьких вспомогательных методов, вроде last(), или методов для обеспечения кросс-браузерности. Я бы не хотел встретиться в коде с такой конструкцией: var a = []; a.loadDOMNodes("div.someclass"); Даже если будет один фреймворк в проекте. |
Цитата:
Цитата:
Цитата:
И ещё, в JS (с версии 1.7) достпен Array comprehensions (который позаимствован из Питона), и там используется синтаксис for / for each ... in: var evens = [i for each (i in [1, 2, 3, 4]) if (i % 2 == 0)]; Андрей Параничев, мне кажется, вторая запись более наглядна, определяет сразу принадлежность метода, нежели первая, глобальная функция: - removeFromArray(array, object); - array.remove(object); А если, ещё назовут не removeFromArray а просто remove - думай потом, к чему этот remove относится (но это уже, конечно, мифический случай)? |
Цитата:
|
Цитата:
|
Цитата:
Ну, Вы получили ответ на первоначальный вопрос? Картина прояснилась? |
Dmitry A. Soshnikov, я так и не понял, зачем вы приводите параллель между питоновским for..in и JS-ным:)
|
Цитата:
|
Цитата:
Цитата:
|
Цитата:
Цитата:
|
Цитата:
И, чисто практическое соображение: массив в JS экономичнее обходится через старый добрый «сишный» for.:) |
Цитата:
for (key, value) in {'a': 1, 'b': 2}.items(): print(key, value) # a 1, b 2 for key in {'a': 1, 'b': 2}: print(key); # a, b JS (1.7): for (var [key, value] in {a: 1, b: 2}) { alert([key, value]); // a,1 ; b,2 } for (var key in {a: 1, b: 2}) { alert(key); // a; b } for / for each ... in равно так же может обходить и массив, не только объект (см., опять же, array comprehensions). var a = [1, 2]; for (var key in a) { alert([key, a[key]]); // 0,1; 1,2 } Цитата:
|
Давайте не будем про JS 1.7. Если вы имеете счастье на нем писать, то я рад за вас.
|
Цитата:
JS (1.5) for (var key in {a: 1, b: 2}) { alert(key); // a; b } Python: for key in {'a': 1, 'b': 2}: print(key); # a, b Вы правильно трактуйте подачу, а не неадекватно ;) Расслабьтесь, это всего лишь форум. В Питоне, for ... in итерирует и словари (равно, как и в JS объекты) и списки (равно, как и в JS - массивы). Сейчас картина прояснилась? Что-то осталось недопонятым? |
Цитата:
Мне непонятны две вещи. * Почему я почти не слышу других мнений, кроме вашего; * Зачем вы меня убеждаете итерировать массив for..in'ом?:) |
Часовой пояс GMT +3, время: 06:01. |