Pull to refresh
1
0
Dmitry Soshnikov @dsCode

User

Send message
> +!{}[0]

Забавный тест ;)

Ещё как варинат: (для квадратных скобок суть меняется):

!+[0]
!-[1]
Уже отмечал в предыдущем топике — полезное дело, молодцы ;)
Замыкания — это вообще основа для позиции, которую вы обозначили ;) Понимание, как они работают и почему — это самые азы для «крепкого JS программера».

Я чисто объективно предложил вам переименовать вакансию в более подходящую — «Фронтэнд разработчик».

Однако, решать вам ;)

Успехов.
> Для нас важно, чтобы писался JS

Ну да, прикладной повседневный (возможно, поверхностный) JS, как дополнение к вакансии «Frontend developer». Я говорю, последнее определение больше подходит для вакансии. Вы из JS вообще мало, что спросили по пунктам (в сущности, если говорить о «крепком» JS программере — вообще ничего не спросили). С другой стороны — для прикладного эффективного Frontend программера, вопросы подходящие.
Вакансия в меньшей мере на JS программера (и тем более «крепкого»). Скорее, на «всё-в-одном фронтэндера»: верстальщика, дизайнера, чего-то там знающего про HTTP протокол, ну и JS вдогонку, чтобы всё это свёрстанное оживить.

Но в целом, для вакансии «всё-в-одном на фронтэнд позицию» может и подойдёт. Однако, прошедший все эти пункты кандидат, может быть весьма посредственным JS программером. Поэтому, возможно лучше изменить вакансию на «Frontend developer» — это будет подразумевать знания JS + всё перечисленное в пунктах.
> -> переопределить toString

Не стоит. Object.prototype.toString — особенный ;)
Да, но это уже полноценные 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. Подробней можно почитать здесь.
А, пожалуй именно возможность писать код после написания кода

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

Это два разных типа функций, с принципиальными отличиями.
А безумие-то в чём? В смысле, конкретно — что-то понравилось или наоборот, что-то не понравилось, что-то не понятно? Или что? Я смутно уловил посыл статьи ;)

Как часто 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», переменная «а» — берётся из глобального контекста, а не из обрамляющего.
Спасибо, хорошая и интересная статья. Сравнительная с компьютерами стилистика тоже вписывается.
> Убедиться, что эти решения плохо работают? :)

А какие решения? И почему плохо? Связываются прототипы, тем самым наследуются. Что здесь не так? Это заложено в идеологию ES. Опять же, чтобы увидеть объектно-ориентированную суть и показать наследование, можно даже не писать какой-то сложный код с конструкторами, иерархией и т.д. Достаточно простейшего примера:

alert(1..toString()); // "1"

Пример показывает, что ES изначально пронизан наследованием и это — в его идеологии. Чтобы поддержать эту идеологию и реализовать её в своих объектах, нужно связать прототипы. Различные решения это и предлагают. Почему же они «плохо работают»?
> Не нужно пытаться всю логику приложения положить на «классы» с наследованием — этот подход идет вразрез с идеологией JS

А почему вразрез? Если цепь прототипов неизменна, то она вполне подходит по цепь наследования. Более того, как я отмечал, разница «класс vs. прототип» в определённых случаях может быть вообще не важна.
> function derivate(o) {
> function F() {}


Для оптимизации, функцию F в данном случае можно создать один раз и использовать повторно.

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

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

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

Да, верно. Но эти причины не столь критичны, как например, проверка входного параметра в родительском конструкторе. Возможны случаи, когда подобным образом вообще не отнаследоваться. Например:

function A(param) {
  if (!param) {
    throw 'Param required';
  }
  this.param = param;
}
A.prototype.x = 10;
 
var a = new A(20);
alert([a.x, a.param]); // 10, 20
 
function B() {}
B.prototype = new A(); // Ошибка

Поэтому, опять же, для этих целей использую обычно методику, предложенную Lasse Reichstein Nielsen с промежуточным пустым конструктором, который и свяжет прототипы. Объект для наследования создаётся именно от этого пустого конструктора, что позволяет избавится от недочётов, описанных выше.

> При всем обилии материалов по данному вопросу, я просто не смог найти в сети достаточно полного обобщающего анализа

Могу порекомендовать Тонкости ECMA-262-3. Часть 7. ООП.

В целом, спасибо за статью и анализ.
Да хватит уже эти фразы слащаво-шаблонные повторять, все всё понимают. Автор лишь анализирует и пытается классифицировать подходы — и в этом, разбирается в ООП в JS.
> автор был уверен что редактирует черновик, пока не увидел эти комментарии. Каким образом автор нажал на кнопочку опубликовать, для самого автора остается загадкой

Говорите о себе в третьем лице? =) Признак мании величия. Шутка ;)
> Человек, возможно не очень хорошо знающий нюансы языка

Ну так а в чём проблема? Значит надо садиться и изучать язык.

Это как, например, математика. Есть школьный уровень. Есть уровень техникума. Университета. Академический уровень.

Так вот, скажите мне, — с какой стати я должен писать на уровне математики 6 класса школы, чтобы код был понят каждым новичком после прочтения книги «Этот занимательный Javascript»? И это не относится сейчас к конкретному случаю с «x++» или «x += 1».

Естественно, основным критерием, в общем случае, должна являться простота чтения кода. Но только не надо перебарщивать, приводя аргументом, что код не поймут новички, которые только прочли первую главу книжки.

В частных случаях, где критерием может быть максимальный выжим ресурсов, могут использоваться нестандартные хакерские способы — но здесь нечитаемость будет уже оправдана.
> крокфорд настаивает, что ++ вредно использовать

Дедушка Крокфорд, действительно, внёс немалый вклад в JS (в основном, прикладного характера). Но только вот не делайте из него «икону», а? Он далеко не безупречен в JS, тоже ошибается, местами знает JS поверхностно, и мысли его порой субъективные.

Если вы будете постоянно «полагаться на истину авторитета, вместо того, чтобы полагаться на авторитет истины, вам будет нелегко» донести свою точку зрения.
> Вместо Math.floor() для экономии размера кода.

Иногда не только экономия размера кода имеет место быть, но и, также, экономия в скорости, как, например, в преобразовании строкового представления в число. Когда однозначно известен формат числа (включая систему счисления), то часто быстрей и удобней использовать ведущий плюс для преобразования (в альтернативу, например parseInt)

var str = '10';
alert(typeof +str); // number
Ой, да ладно, минусовать-то сразу ;) Я хотел сказать, что не нужно её воспринимать как «спасение» от «выдуманных проблем». В целом же — тулза, конечно, полезная.

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity