Pull to refresh

Comments 64

Почувствовал себя дибилом.(((
moooV — простите если обидел, если обидел — мне стыдно.
но, если бы я сам до конца понимал то, что я написал, то статьи бы здесь не было :)
Да нет, не обидел.))) Просто вынос мозга качественный.)))
Попробуйте отследить логику парсера:

~((['"]).*?(?<!\\)\2|\w*\s*\(((?:(?R)|.)*?)\)|(?!(?:is\s+not|is|not\s+eq|eq|neq?|gt|lt|gt?e|ge|lt?e|mod)\W)_?[\$#]?\w+#?(?:\[(?:(?R)|\w+|((?:[^\]'"]*(?:(['"]).*?(?<!\\)\5)?)*))*?\]|\.[\$#]?\w+#?|->\s*_?[\$#]?\w+#?(?:\(((?:(?R)|.)*?)\))?)*|-?\d+|(?<=^|[\s\)\:\.=+\-<>])(?!(?:is\s+not|is|not\s+eq|eq|neq?|gt|lt|gt?e|ge|lt?e|mod)\W)(?:\w+)(?=$|[\s\|\.\:\(=+\-<>]))(\s+(?:instanceof (?:\w+|(?R))|is(?:\s+not)?\s+(?:odd|div|even)\s+by\s+(?:-?\d+|(?R))|is(?:\s+not)?\s+(?:odd|even)))?((?:\|@?\w+(?:\:(?:\w*\(((?:(?R)|.)*?)\)|[\$#]\w+#?(?:\[(?:(?R)|((?:[^\]'"]*(?:(['"]).*?(?<!\\)\11)?)*))*?\]|\.[\$#]?\w+#?)*|[^'"\:]*(?:[^'"\:]*(['"]).*?(?<!\\)\12[^'"\:]*)*))*)*)|((?<=\s|\))(?:is\s+not|is|not\s+eq|eq|neq?|gt|lt|gt?e|ge|lt?e|mod)(?=\s|\()|(?:not\s+))~si
Если самую большую плашку кода взять и засунуть в файлик mix.js
то следующий пример поможет понять, что она делает. Там банальность.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.1 Strict//EN">
<html>
<head>
<title>Test</title>
<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8">
</head>
<body>
<span id = "loadString" style = "font-family: Tahoma; font-size: 11px; padding: 0px; padding-left: 15px"> asdf</span>
</body>
<script language = "Javascript" type = "text/javascript" src = "mix.js"></script>
<script language = "Javascript" type = "text/javascript">
alert(mix("loadString"))
alert(mix.s("loadString"))
alert(mix.In("loadString"))
</script>
</html>


* This source code was highlighted with Source Code Highlighter.
считаю, что очевидного смысла в последней конструкции нет совсем.


Это такое быстрое inline-создание экземпляра класса :)
Безумие, достойное уважения!
Хотя насчет отсутствия смысла в
var My_Function_Name = new function([parametrs]){
[Operaitors];
}

, я бы поспорил :)
так рад, что тут всем весело!

;^)

попытаюсь ответить конструктивно про «new function»:

позволил там себе оставить путь к отступлению, теперь вот, воспользуюсь им:
там же написано «ОЧЕВИДНОГО смысла», и полностью поддерживаю kurokikaze.
т.е. dio — я не против совсем, надо — значит надо! :)
Очевидность — штука весьма субъективная IMHO.

mrhard — я ждал, надеялся, и верил, что будет хотя бы один такой комментарий.
Сапасибо, камрад! «Щас спаю!» ( © — «совецкий мульт»: «Жил был Пёс»)

Прошу прощенья у Всех тех, кто читал статью до 22:30 по Москве.
Там в п.1 не хватало этого:

mix.s = function(id){ return mix(id).style; };
*


На смысл не влияет, но понимание дальнейшего может и «выключить».
Хотя в большой плашке этот код, конечно, есть.

Статью поправил.

Простите ещё раз.
??? — терминология

статьи, посты, треды — нужна разница?
не про это. слишком художественно для статьи (с позиции человека ожидающего уяснить что-то новое)
> Некоторые особенные создания даже делают так:
>
> (function(){
> var My_Function_Name = new function([parametrs]){
> [Operaitors];
> }
> })()
> *
>
> очевидного смысла в последней конструкции нет совсем, но, может, есть неочевидный…

смысл этой конструкции просто огромен… на этом построено все ООП яс
в данном случае функция является конструктором и мы создаем экземпляр класаа
Я не спорю, если понятна разница между:

var f_name = new function(){},
var f_name = function(){},
var f_name = new Function([args], [f_body]);
Поправил немного текст, последнего предложения этой цитаты,
может быть не будет так бросаться в глаза…
интересно, особенно если данную статью рассматривать в аспекте лексических парсеров/генераторов!

Надо подумать, т.к. есть желание/необходимость сделать нечто подобное.
Большое спасибо за толчек в нужном направление!
Такое даже в голову не приходило — слишком мало опыта в подобном. JS — это хобби.
Замыканиями, наследованием и всевозможными манипуляциями с конструктором Function нужно пользоваться с умом. И моё мнение — чем проще код, тем лучше, и если есть возможность избежать извращений — лучше их избежать.

new Function([«x», «y»], (function(){ return «return x*y»; })()) — изврат
new Function([«x», «y»], «return x*y») — так лучше
new Function(«x», «y», «return x*y») — так ещё лучше
function(x, y) {return x*y} — так оптимально

Насчёт new function(){...} — жесть, конечно :)
Есть много памяти. Но так, к примеру, можно реализовать getter'ы и setter'ы (определив их в конструкторе, а атрибуты сделав просто переменными)
Меня не только это «удивляет».
А, пожалуй именно возможность писать код после написания кода.
И переписывать уже имеющийся код при необходимости (изменилась модель поведения, например).

А тут, получается, инструментарий готов еще во времена выхода стандарта для JS.
Я бы сказал, что это как игра в страйкбол — всё основывается лишь на доброй совести участника (тут — разработчика).

Да, можно менять существующий код. Ну так это же здорово! К примеру, если 3d-party JS-библиотека дала сбой, новая версия выйдет не скоро, но очень не хочется менять её исходный код — можно написать патч в отдельном файлике, который будет очень бережно исправлять ошибку в этой либе. А как выйдет новая версия с исправлением — выкинул патч и забыл. Вот (я пользуюсь таким подходом в работе с ExtJS)
А, пожалуй именно возможность писать код после написания кода

Да, это непосредственно связано с динамикой языка ;) Можно менять объекты в рантайме, создавать/удалять/модифицировать свойства/методы, менять тела функций и т.д. Схожую идеологию (в некоторых аспектах) можно наблюдать во многих динамических языках, например, в Ruby или Python.
new Function(«x», «y», «return x*y») — так ещё лучше
function(x, y) {return x*y} — так оптимально

Это два разных типа функций, с принципиальными отличиями.
Да, но на данном примере они идентичны
Да, если кому интересены извращения с Javascript: для начала выполните следующий код через строку адреса (не бойтесь, это не форматнёт ваш винт):

javascript:_=~[];_={___:++_,$$$$:(![]+"")[_],__$:++_,$_$_:(![]+"")[_],_$_:++_,$_$$:({}+"")[_],$$_$:(_[_]+"")[_],_$$:++_,$$$_:(!""+"")[_],$__:++_,$_$:++_,$$__:({}+"")[_],$$_:++_,$$$:++_,$___:++_,$__$:++_};_.$_=(_.$_=_+"")[_.$_$]+(_._$=_.$_[_.__$])+(_.$$=(_.$+"")[_.__$])+((!_)+"")[_._$$]+(_.__=_.$_[_.$$_])+(_.$=(!""+"")[_.__$])+(_._=(!""+"")[_._$_])+_.$_[_.$_$]+_.__+_._$+_.$;_.$$=_.$+(!""+"")[_._$$]+_.__+_._+_.$+_.$$;_.$=(_.___)[_.$_][_.$_];_.$(_.$(_.$$+"\""+_.$_$_+(![]+"")[_._$_]+_.$$$_+"\\"+_.__$+_.$$_+_._$_+_.__+"(\\\"\\"+_.__$+_.__$+_.___+_.$$$_+(![]+"")[_._$_]+(![]+"")[_._$_]+_._$+", \\"+_.__$+_.__$+_.___+_.$_$_+_.$_$$+"\\"+_.__$+_.$$_+_._$_+_.$_$_+"\\"+_.__$+_.$_$+_.___+_.$_$_+_.$_$$+"\\"+_.__$+_.$$_+_._$_+"!\\\")"+"\"")())(); void 0;

А потом попытайтесь понять, как оно сработало :) Кому надо, могу сказать, где взял.
или руки у меня растут чуть ниже плеч
или парсер чего покушал
первоисточник в студию!
спасибки теперь сработало
крутой обфускатор
Обфусцированный код мне почему-то что-то напоминает:

javascript:chicken=~[];chicken={___:++chicken,$$$$:(![]+"")[chicken],__$:++chicken,$_$_:(![]+"")[chicken],_$_:++chicken,$_$$:({}+"")[chicken],$$_$:(chicken[chicken]+"")[chicken],_$$:++chicken,$$$_:(!""+"")[chicken],$__:++chicken,$_$:++chicken,$$__:({}+"")[chicken],$$_:++chicken,$$$:++chicken,$___:++chicken,$__$:++chicken};chicken.$_=(chicken.$_=chicken+"")[chicken.$_$]+(chicken._$=chicken.$_[chicken.__$])+(chicken.$$=(chicken.$+"")[chicken.__$])+((!chicken)+"")[chicken._$$]+(chicken.__=chicken.$_[chicken.$$_])+(chicken.$=(!""+"")[chicken.__$])+(chicken._=(!""+"")[chicken._$_])+chicken.$_[chicken.$_$]+chicken.__+chicken._$+chicken.$;chicken.$$=chicken.$+(!""+"")[chicken._$$]+chicken.__+chicken._+chicken.$+chicken.$$;chicken.$=(chicken.___)[chicken.$_][chicken.$_];chicken.$(chicken.$(chicken.$$+"\""+chicken.$_$_+(![]+"")[chicken._$_]+chicken.$$$_+"\\"+chicken.__$+chicken.$$_+chicken._$_+chicken.__+"(\\\"\\"+chicken.__$+chicken.__$+chicken.___+chicken.$$$_+(![]+"")[chicken._$_]+(![]+"")[chicken._$_]+chicken._$+", \\"+chicken.__$+chicken.___+chicken.$__+chicken._$+chicken._+"\\"+chicken.__$+chicken.$__+chicken.$$$+" \\"+chicken.__$+chicken._$$+chicken._$_+chicken._$+"\\"+chicken.__$+chicken.$_$+chicken.$$_+"\\"+chicken.__$+chicken.$__+chicken.$$$+"\\"+chicken.__$+chicken.$_$+chicken._$$+chicken.$$$_+"\\"+chicken.__$+chicken.$$_+chicken._$_+"\\\")"+"\"")())(); void 0;
в этом и смысл обфускации, что бы одни чикены и виделись
цель достигнута
Хм. Забавно. Но почему-то не работает из консоли Firebug.
Подозреваю, что взяли из Brainfuck'а :)
А безумие-то в чём? В смысле, конкретно — что-то понравилось или наоборот, что-то не понравилось, что-то не понятно? Или что? Я смутно уловил посыл статьи ;)

Как часто JS программисты задумываются над [function statement]?

Лучше не путать терминологию. В ECMAscript существует три вида функций: декларации функции (Function Declaration), функции-выражения (Function Expression) и функци, созданные конструктором Function.

А вот Function statement — это расширение Gecko для описания функций в блоках. Формально, функция не может быть описана в виде декларации в блоке, по грамматике должна быть ошибка. Но ни одна из реализаций не выбрасывает исключение, а обрабатывает этот случай. И только в Firefox (Gecko, *monkey) обработка этого случае наиболее логичная:

if (true) {
  function a() {
    alert(1);
  }
} else {
  function a() {
    alert(2);
  }
}
a();

Потестируйте в разных браузерах. Во всех, кроме Firefox, функция «а» будет выводить 2, даже, несмотря на то, что ветвь else никогда не выполнится. А дело в том, что реализации создают здесь Function Declaration. И только Firefox использует расширение синтаксиса, создавая правильно функцию по условию. Это расширение называется у них Function statement. Подробней можно почитать в конце этого раздела.

Поэтому, все эти виды функций имеют принципиальное отличие друг от друга.

Персональное безумие началось с «Вики-англичанки»: статя
про Javascript.

Там внизу есть Syntax and semantics — замечательный пример.

После этого «щелкнула» известная многим
набла.

И, главное — последующий
тред.

«Известная набла» неточная и содержит кучу недочётов.

Если заинтересовались Javascript-ом глубоко, могу порекомендовать эти статьи — javascript.ru/ecmascript-in-detail.

И в частности этого: var My_Function_Name = function([parametrs]){… var My_Function_Name = new function([parametrs]){… очевидного смысла в последней конструкции нет совсем, но, может, есть неочевидный…

В первом случае создаётся функция (Function Expression), во втором — порождается объект от анонимного конструктора. Это два разных случая.

mix[i] = new Function(pf_T, pf_B);

Функции, созданные с помощью конструктора Function, имеют ряд особенностей, не всегда полезных (особенно в описываемом случае). Во-первых, их [[Scope]] содержит всегда только глобальный объект:

var a = 10;
function x() {
  var a = 20;
  var b = 30;
  var y = new Function('alert(a); alert(b);');
  y(); // 10, "b" is not defined
}

Видно, что в [[Scope]] функции «y» отсутствует объект активации контекста функции «x»: не доступна переменная «b», переменная «а» — берётся из глобального контекста, а не из обрамляющего.
Выглядит очень странно. Несложно понять все эти возможности, но зачем же так писать
var pfb = function(el){ //Prepare Functions Body
если можно
var prepareBody = function(el){

К тому же, зачем такой странный pfb? Мне кажется там можно обойтись одной или двумя функциями с параметрами вместо динамической генерации.

В целом, этот код очень плохо читается.
эмм — я не профессиональный программист, а там просто кусок реального моего кода.
согласен, нужно было как-то «допилить» для читабельности.
поправил код, наверное так будет проще :)
if (true) {
  a = function() {
    alert(1);
  }
} else {
  a = function() {
    alert(2);
  }
}
a();

а так, понятное дело, работает везде :)
Да, но это уже полноценные Function Expression (FE), которые будут созданы на этапе интерпретации кода. А в описанном выше случае, реализации трактуют функции, как Function Declaration (FD) и создают их на этапе входа в контекст (т.е. ещё до начала интерпретации кода), поэтому функция «а» будет доступна даже выше if-а. Firefox поступил логичней — воспользовался правом на расширение синтаксиса (см. 16. Errors ECMA-262-6) и ввёл Function statements ;)

Только надо быть осторожным даже при описании Function Expression в этом случае. В IE есть баг, когда FE содержит опциональное имя. В этом случае, Jscript (IE) трактует такие функции, как FD и создаёт их на этапе входа в контекст:

a(); // 2 - FD, созданная при входе

if (true) {
  a = function a() {
    alert(1);
  }
} else {
  a = function a() {
    alert(2);
  }
}

a(); // 1 - FE, созданная при интерпретации

Более того, IE создаёт в этом случае два объекта — и FD и FE. Подробней можно почитать здесь.
dsCode — Cупер! Спасибо.

Безумие у меня в голове. Я поначалу просто не поверил что так можно делать — недостаток опыта.
Сидел, читал маны, и потом проверял. Читал ту наблу, ничего у меня не работало пока не полез в тред.

Исходная у меня была, конечно, задачка, но к сути статьи отношения имеет мало.
Впрочем…: хотел сделать так, чтобы было как можно меньше кода — задекларировать объект, сразу, пусть функцию (ведь ничего другого не получается кроме базовых литералов), а потом через [] или {} как-нибудь дописывать свойства. Ну, чтобы не писать имя объекта все время.
т.е. mix = function mix.s = function

а хотелось просто mix = function и s = function, и чтобы s было сразу для mix.

Не знаю, понятно ли объяснил.

Но потом это стало не так интересно как «программирование программирования».

По поводу остального текста комментария — целиком и полностью согласен, к сожалению, не хватило опыта чтобы в статье оказались замечания, подобные Вашим. Например — я знал только про [[Scope]]. А про то, что Function statement это только Gecko движок — вообще не слышал.
Это как пёрл, в котором можно сделать простые вещи сложночитаемыми.
Моё глубокое имхо, это избыточная функциональность, которой пользуются единицы на фаллометрических соревнованиях «Хрен прочтёшь мой код»
Идея не в этом.
Если Вы про «большую плашку кода» — выкиньте и забудьте, она ни о чем, это просто был пример.
Одна из идей в том, что код можно «дописывать» непосредственно как строку.
И для этого весь инструментарий был еще в «затертых годах» «динозавровой эры ПК».
Возможности большинства интерпритируемых языков позволяют делать много разных извращений (в хорошем смысле), но оборотной стороной этого будет плохая поддерживаемость кода (в силу многих причин — непопулярность извращений, сложность отладки инлайнового строкового кода и пр).
Если всё это затевалось в целях академического интереса, типа «эвона как оно умеет», то я и сам любитель такого :) А в промышленном использовании я бы за это разработчикам руки отрывал
Язык называется «Перл» (Perl), «пёрл» (pearl) — это «жемчужина».
Google.com -> perl pronunciation -> I Feel Lucky -> forvo.com/word/perl/

Но спорить с вами не буду, пусть будет «перл»
Да, я знаю как это говорят на английском, слышал в разговоре (да и в словарях можно увидеть, что оба слова пишутся как p(перевёрнутая «e»)rl). В русском традиция другая.
Да не спорю, я, не спорю :) Просто показал что меня с толку сбило
Некоторые особенные создания даже делают так:… new function
Не так делают. Делают вот так: new Function('параметр, параметр', 'тело')
А… понял. Тут порождение сразу идёт, ошибся, так делают, конечно.
UFO just landed and posted this here
(parent= function(){}).prototype= new function(){
this.a= 1;
};

(child= function(){}).prototype= new function(){
parent.prototype.constructor.apply( this );
this.b= 2;
};

var obj= new child;
alert( obj.a + obj.b );
я не понял какую задачу ты решал, но решил ты её не правильно
В статье поехали стили при оформлении блоков кода, вероятно это связано с обновлением Хабром своего движка без учета обратной совместимости или с тем, что автор забросил свою статью, считая её более неактуальной.
поправил, не уверен, что актуально, да
Sign up to leave a comment.

Articles