Java Script

Описание: Наиболее перспективное направление развития компьютерных наук. Надо быть в теме!

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Чт, 22 мая 2014, 12:25:13

Расстановка переносов в релизных джаваскриптах.
http://jsbeautifier.org/

Отладка в хроме
https://learn.javascript.ru/debugging-chrome

To pdf в хроме, js
Консольная

Код: Выделить всё

wkhtmltopdf

использует webkit, работает быстро

Типы тут
http://habrahabr.ru/post/159313/
http://habrahabr.ru/post/120193/
http://habrahabr.ru/post/120192/
Спойлер
Подводные камни JavaScript
JavaScript*
Мне очень нравится JavaScript и я считаю его мощным и удобным. Но для большинства начинающих JS-программистов, много проблем создаёт недопонимание аспектов языка. Часто конструкции языка ведут себя «нелогично». В данной статье я хочу привести примеры «граблей», на которые я наступил; объяснить поведение языка и дать пару советов.



Типы

Как написано в спецификации ECMAScript, всего существует 6 типов:
Undefined
Null
Boolean
String
Number
Object

Все значения должны принадлежать к ним. В JS есть оператор typeof, который, как казалось бы, должен возвращать тип объекта. Казалось бы, один из перечисленных. Что получается на самом деле:

typeof 5; //"number", ок, похоже на правду
typeof "hello"; //"string"
typeof true; //"boolean"
typeof undefined; //"undefined"
typeof {}; //"object". Пока 5 из 5
typeof null; //"object". WTF?
typeof function(){}; //"function". Разве у нас есть тип function?

Проблема: несмотря на то, что тип у null — Null, оператор возвращает 'object'; а тип у функции — Object, оператор возвращает 'function', а такого типа нет.
Объяснение: typeof возвращает не тип, а строку, которая зависит от аргумента и не является именем типа.
Совет: забудьте про типы. Серьезно, я считаю что знание 6 типов JS не даст вам пользы, а оператор typeof используется довольно часто, поэтому лучше запомнить результаты его работы:
Тип аргумента Результат
Undefined undefined
Null object
Boolean boolean
Number number
String string
Object (результаты оператора new, inline-объекты ({key: value})) object
Object (функции) function

Магические значения: undefined, null, NaN

В спецификации описаны так:

undefined value — primitive value used when a variable has not been assigned a value
Undefined type — type whose sole value is the undefined value
null value — primitive value that represents the intentional absence of any object value
Null type — type whose sole value is the null value
NaN — number value that is a IEEE 754 “Not-a-Number” value


У себя в голове я держу следующее:
undefined — значение переменной, которая не была инициализирована. Единственное значение типа Undefined.
null — умышленно созданный «пустой» объект. Единственное значение типа Null.
NaN — специальное значение типа Number, для выражения «не чисел», «неопределенности». Может быть получено, например, как результат деления 0 на 0 (из курса матанализа помним, что это неопределенность, а деление других чисел на 0 — это бесконечность, для которой в JS есть значения Infinity).

С этими значениями я обнаружил много «магии». Для начала, булевы операции с ними:
!!undefined; //false
!!NaN; //false
!!null; //false
//как видим, все 3 значения при приведении к boolean дают false

null == undefined; //true

undefined === undefined; //true
null === null; //true

NaN == undefined; //false
NaN == null; //false

NaN === NaN; //false!
NaN == NaN; //false!

Проблема: с чем бы мы ни сравнивали NaN, результатом сравнения всегда будет false.
Объяснение: NaN может возникать в результате множества операций: 0/0, parseInt('неприводимая к числу строка'), Math.sqrt(-1) и было бы странно, если корень из -1 равнялся 0/0. Именно поэтому NaN !== NaN.
Совет: не использовать булевы операторы с NaN. Для проверки нужно использовать функцию isNaN.



typeof a; //'undefined'
a; //ReferenceError: a is not defined

Проблема: оператор typeof говорит нам, что тип необъявленной переменной — undefined, но при обращении к ней происходит ошибка.
Объяснение: на самом деле, есть 2 понятия — Undefined и Undeclared. Так вот, необъявленная переменная является Undeclared-переменной и обращение к ней вызывает ошибку. Объявленная, но не инициализированная переменная принимает значение undefined и при обращении к ней ошибок не возникает.
Совет: перед обращением к переменной, вы должны быть уверенны, что она объявлена. Если вы обратитесь к Undeclared-переменной, то код, следующий за обращением, не будет выполнен.



var a; //вновь объявленная переменная, для которой не указано значение, принимает значение undefined
console.log(undefined); //undefined
console.log(a); // undefined
a === undefined; //true
undefined = 1;
console.log(undefined); //1
a === undefined; //false

Проблема: в любой момент мы можем прочитать и записать значение undefined, следовательно, кто-то может перезаписать его за нас и сравнение с undefined будет некорректным.
Объяснение: undefined — это не только значение undefined типа Undefined, но и глобальная переменная, а значит, любой может её переопределить.
Совет: просто сравнивать переменные с undefined — плохой тон. Есть 3 варианта решения данной проблемы, для создания «пуленепробиваемого» кода.
Вы можете сравнивать не значение переменной, а её тип: «typeof a === 'undefined'».
Использовать паттерн immediately-invoked function:

(function(window, undefined){
//т.к. второй аргумент не был передан, значение переменной undefined будет «правильным».
}(this));

Для получения реального «undefined»-значения можно использовать оператор void (кстати, я не знаю другого применения этому оператору):

typeof void(0) === 'undefined' // true




Теперь попробуем совершить аналогичные действия с null:
console.log(null); //null
null = 1; //ReferenceError: Invalid left-hand side in assignment

Проблема: несмотря на некоторые сходства между null и undefined, null мы перезаписать не можем. На самом деле проблема не в этом, а в том, что язык ведёт себя нелогично: даёт перезаписать undefined, но не даёт перезаписать null.
Объяснение: null — это не глобальная переменная и вы не можете её создать, т. к. null — зарезервированное слово.
Совет: в JavaScript не так много зарезервированных слов, проще их запомнить и не использовать как имена переменных, чем вникать, в чём проблема, когда она возникнет.



И теперь сделаем тоже самое с NaN:
console.log(NaN); //NaN
NaN = 1;
console.log(NaN); //NaN
isNaN(NaN); //true

Проблема: при переопределении undefined всё прошло успешно, при переопределении null возникла ошибка, а при переопределении NaN операция не вызвала ошибки, но свойство не было переопределено.
Объяснение: нужно понимать, что NaN — переменная глобального контекста (объекта window). Помимо этого, к NaN можно «достучаться» через Number.NaN. Но это неважно, ниодно из этих свойств вы не сможете переопределить, т. к. NaN — not writable property:
Object.getOwnPropertyDescriptor(window, NaN).writable; //false
Object.getOwnPropertyDescriptor(Number, NaN).writable; //false

Совет: как JS-программисту, вам нужно знать об атрибутах свойств:
Атрибут Тип Смысл
enumerable Boolean Если true, то данное свойство будет участвовать в циклах for-in
writable Boolean Если false, то значение этого свойства нельзя будет изменить
configurable Boolean Если false, то значение этого свойства нельзя изменить, удалить и изменить атрибуты свойства тоже нельзя
value Любой Значение свойства при его чтении
get Object (или Undefined) функция-геттер
set Object (или Undefined) функция-сеттер
Вы можете объявлять неудаляемые или read-only свойства и для созданных вами объектов, используя метод Object.defineProperty:
var obj = {};
Object.defineProperty(obj, 'a', {writable: true, configurable: true, value: 'a'});
Object.defineProperty(obj, 'b', {writable: false, configurable: true, value: 'b'});
Object.defineProperty(obj, 'c', {writable: false, configurable: false, value: 'c'});

console.log(obj.a); //a
obj.a = 'b';
console.log(obj.a); //b
delete obj.a; //true

console.log(obj.b); //b
obj.b = 'a';
console.log(obj.b); //b
delete obj.b; //true

console.log(obj.c); //c
obj.b = 'a';
console.log(obj.c); //c
delete obj.b; //false


Работа с дробными числами

Давайте вспомним 3-й класс и сложим несколько десятичных дробей. Результаты сложения в уме проверим в консоли JS:
0.5 + 0.5; //1
0.5 + 0.7; //1.2
0.1 + 0.2; //0.30000000000000004;
0.1 + 0.7; //0.7999999999999999;
0.1 + 0.2 - 0.2; //0.10000000000000003

Проблема: при сложении некоторых дробных чисел, выдаётся арифметически неверный результат.
Объяснение: такие результаты получаются из-за особенностей работы c числами с плавающей точкой. Это не является особенностью JavaScript, другие языки работают также (я проверил в PHP, Python и Ruby).
Совет: во-первых, вы, как программист, обязаны знать об особенностях работы компьютера с числами с плавающей точкой. Во-вторых, в большинстве случаев достаточно просто округлять результаты. Но, если вдруг необходимо выдавать пользователю точный результат, например, при работе с данными о деньгах, вы можете просто умножать все аргументы на 10 и результат делить обратно на 10, например так:
function sum() {
var result = 0;
for (var i = 0, max = arguments.length; i< max; i++ ) {
result += arguments[i]*10;
}
return result / 10;
}
sum(0.5, 0.5); //1
sum(0.5, 0.7); //1.2
sum(0.1, 0.2); //0.3
sum(0.1, 0.7); //0.8
sum(0.1, 0.2, -0.2); //0.1


Вывод

Это только несколько необычных примеров с непредсказуемым результатом. Если помнить о них, то получится не наступить на те же грабли и быстро понять, в чём проблема. Если найдёте новый «нелогичный» кусок кода, то попробуйте осознать, что происходит с точки зрения языка, почитав спецификацию или MDN.

Сад
http://shamansir.github.io/JavaScript-Garden/
Плэйграунд
http://www.objectplayground.com/

вопросы на собеседовании
http://habrahabr.ru/post/239065/
Спойлер
JavaScript. Вопросы на собеседовании
JavaScript*
Не так давно озадачился поиском работы, в связи с чем посетил n-нное количество собеседований и услышал много интересных вопросов. По сети гуляет много статей с вопросами по JS, поэтому постараюсь выбрать вопросы, которые ещё не видел. Здесь нет вопросов типа Что такое замыкание?, Наследование в JavaScript или Сделайте ajax запрос на VanillaJS. Кстати советую поискать ответы на эти вопросы, прежде чем читать статью :) Под катом вопросы типа «с подвохом». Вряд ли какой-то из них попадётся вам, но, надеюсь, статья настроит вас на «подвоховое» мышление, и напомнит некоторые скользкие места и подводные камушки javascript.


Hoisting

Hoisting — всплытие переменных объявленных в функции.Здесь можно подробно узнать о том как это бывает.
А вот интересный вопрос:

(function() {
f();

f = function() {
console.log(1);
}
})()

function f() {
console.log(2)
}

f();


Что мы увидим в консоли?

Ответ

Если вы сходу уловили подвох предыдущей задачи — не обольщайтесь. Вот ещё интересный пример кода:

(function() {
var x = 1;

function x() {};

console.log(x);
})()


Что теперь мы увидим в консоли?

Ответ

Ну и напоследок. Напомню советы Дугласа Крокфорда: избегать слабых сторон языка и использовать сильные и использовать JSLint.
Чтобы не наткнуться на такие сюрпризы можно взять за привычку самому выносить var в начало функции и объявлять функцию через function expression

Передача по ссылке


Наверное все знают что все объекты передаются в javascript по ссылке:

var obj = {
a: 1
};

(function(obj) {
obj = {
a: 2
};

})(obj);

console.log(obj.a);


Не знаю как вы, а я засыпался на этом вопросе. Я точно знал что объект не измениться после вызова функции, но объяснить почему так и не смог.

А вот почему!

Контекст выполнения


Контекст выполнения функции — мощный и выразительный механизм, если умело его использовать. Правда есть несколько моментов о которых не стоит забывать. Простой пример. Рассмотрим класс который логгирует некие действия.

Logger = function(logFn) {

_logFn = logFn;

this.log = function(message) {
_logFn(new Date() + ": " + message);
}
}

var logger = new Logger(console.log);

logger.log("Hi!");
logger.log("Wazzup?");


Что будет в консоли? Как починить?

Ответ

UPD: ещё набор из 5 годных интересных вопросов по теме
javascript, вопросы, собеседование
+27

60355

554


@AvrGavr карма8,0 рейтинг0,0
Похожие публикации

Как создать свой собственный браузер для Windows 10 на HTML и JavaScript (10)
Рецепт вращения планет в космосе на HTML5 + JavaScript (14)
Введение в стрелочные функции (arrow functions) в JavaScript ES6 (45)
Горизонтальное масштабирование небольших Web-приложений на Java (вопросы собеседований) (87)
ASP.NET, поиск работы, вопросы собеседований (78)
Комментарии (157)

+51 forgotten 4 октября 2014 в 01:23#
А объясните мне кто-нибудь — зачем это спрашивать на собеседовании?
Задачки, кстати, тривиальные.
+3 norlin 4 октября 2014 в 01:28#↵↑
Чтобы понять, знаком ли человек именно с Javascript, или только с jQuery API. И насколько хорошо знаком.
+33 forgotten 4 октября 2014 в 01:33#↵↑
Т.е. знать JavaScript == быть в курсе, каков порядок инициализации переменных и функций?
А у вас в проекте где-то есть код, где это важно?
+12 norlin 4 октября 2014 в 01:40 (комментарий был изменён)#↵↑
В том числе – да. Этот самый Hoisting, при незнании, может много времени на дебаг отнять… Некоторые, например, ещё любят объявлять переменные\функции внутри блоков if..else.

Лично я когда собеседовал на JS-вакансии спрашивал в первую очередь про понимание разницы между == и ===, про замыкания, hoisting ну и дальше уже по мелочи.

С другой стороны, даже если в проекте подобного кода нет, такие вопросы позволяют в какой-то степени оценить опыт разработчика.
+1 Aingis 4 октября 2014 в 12:42 (комментарий был изменён)#↵↑
Избежать таких багов можно простейшим кодстайлом, когда функции называются глаголами, а переменные существительными. Исключением могут быть разве что булевы переменные вида isSmth, hasSmth. Естественно, функции не должны так называться, а иметь имена вроде checkSmth.
–1 norlin 4 октября 2014 в 12:52#↵↑
Допустим, это возможно на каком-то отдельном проекте. Но вопрос-то про собеседование. Цель – оценить опыт человека, понять, сможет ли он работать сразу, или будет по каждой мелочи спрашивать «а как оно работает?».
+11 Zav 4 октября 2014 в 12:55#↵↑
Смотри предыдущие работы человека.
Всё, по другому никак.
Я нескольких нулевых ребят учил проходит такие интервью, и они учились дальше прямо на работе. Никто ничего так и не заметил.
+1 norlin 4 октября 2014 в 13:01#↵↑
Безусловно, другие работы тоже имеют значение. На какие-то очень крутые вакансии даже можно давать собственное тестовое задание (хотя лично я только 1-2 раза брался за тестовое задание, т.к. обычно было много других предложений, без него).

Более того, если человек приходит на крупный проект с большим объёмом уже написанного кода – ему в любом случае придётся чему-то учиться, узнавать как всё устроено. Намного эффективнее, если при этом человеку не придётся ещё и разбираться с особенностями языка.

Ещё раз: это не единственный (и не главный) критерий. Один из. Можно даже сказать опциональный (для простых проектов такое явно излишне спрашивать).
+1 Zav 4 октября 2014 в 13:05#↵↑
На крупном проекте задержка даже в месяц не будет иметь значения, так что нет, не эффективнее.
Обычно, на крупных проектах, и так много затыков и постоянный недостаток специалистов.

Если речь идет о стартапе, где всё сейчас и срочно, то ещё возможно. И то примеры нужны не как в статье, а более очевидные — потому что именно такие будут в коде. Если в проекте встречается повсеместно то, что в посте, и надо всё-всё срочно, то лучше отказаться от работы в такой компании, насколько бы привлекательно это не было.
+1 norlin 4 октября 2014 в 13:10#↵↑
Ну вот видите, и для собеседуемых, подобных вам, такие вопросы полезны в какой-то степени. Позволяют оценить компанию.
+1 Kite 5 октября 2014 в 09:50 (комментарий был изменён)#↵↑
По поводу таких вопросов — я на собеседовании также такие вопросы задаю, но лишь чтобы услышать как человек думает и рассуждает. Не всегда обязательно ответить. Почему я их задаю: когда человек может на такое ответить — он сам сможет создать стайл гайд, а не будет выучивать правила. На проекте часто нет времени на то, чтобы апдейтить стайл гайд увидев очередной «перл» гугл-драйвен девелопмента. Человек сам должен осознавать, почему это включено в гайд и почему так не стоит делать.
И еще, на больших проектах не всегда все медленно и спокойно. Разработка всегда зависит от потребностей бизнеса. А в бизнесе важно вовремя выпустить продукт.
0 Zav 5 октября 2014 в 12:09#↵↑
Именно что первично это выпускать продукт :-)
Очень часто в крупных проектах делают «не то» годами, не говоря уже про какой-то там месяц. Это издержки масштаба.
+3 forgotten 4 октября 2014 в 15:38#↵↑
Чего тут учить. Открываешь Флэнагана и заучиваешь. Фактически, как экзамен сдать.
Надо ли уточнять, что сдать экзамен != наличию знаний по предмету?
+2 Zav 4 октября 2014 в 15:40#↵↑
Весь тред я и пытаюсь это донести norlin'у :-)
+1 Aingis 4 октября 2014 в 13:23#↵↑
Вы же сами комментарием выше говорили про дебаг на реальном проекте. Так вот на реальном проекте хороший кодстайл предотвращает и такую проблему.
0 norlin 4 октября 2014 в 13:30#↵↑
Ок. Что делать, если нет хорошего кодстайла? Что делать, если проект только стартует и набирают команду? Как вообще оценить навыки человека? А если у него нет кода, который может показать?
–1 Zav 4 октября 2014 в 13:33#↵↑
1) Узнать, почему у него совсем нет кода, который может показать.
2) Забить на код и смотреть на РЕЗУЛЬТАТ его работ.
+2 norlin 4 октября 2014 в 13:38#↵↑
1. Ок, весь код под NDA. Что дальше?
2. То есть, принять на работу вслепую и надеяться на лучшее? Вы оптимист! Давайте я к вам приду на 150к в месяц, поговнокожу, получу 150к и уйду?
+2 Zav 4 октября 2014 в 13:50#↵↑
1) Смотреть на результат работ, а не на код. Пишу в 4й раз уже.
2) При чем тут в слепую? Можно нормально пообщаться и понять подходит ли вам кандидат.

Например у меня почти весь код под NDA, однако это не мешает мне рассуждать как можно решить тот или иной класс задач. При этом не показывая код. Код и особо нужен, на самом деле. Это как просить сантехника гаечный ключ показывать. Можно же узнать о репутации человека, позвонить по предыдущим местам работы и т.п. Способов масса, зачем зацикливаться на коде вообще?
0 norlin 4 октября 2014 в 15:04#↵↑
1. Вот этого я никак не пойму. Как можно вслепую взять человека, и лишь потом оценивать его? Это ещё возможно на Junior позициях, но никак не на полноценного разработчика, не говоря уже о Senior.
2. Как это «нормально пообщаться», не задавая технических вопросов? За кружкой пива, что ли: «свой кореш – берём!»?

С этим я и не спорю, множество раз тут написал – эти вопросы лишь часть собеседования.
зачем зацикливаться на коде вообще?
Уже откровенный троллинг, погляжу. Ок, спасибо за дискуссию.
0 Zav 4 октября 2014 в 15:08#↵↑
1. Ещё раз. Не в слепую, а посмотрев на его результат работы.
2. Не стоит перескакивать с темы на тему. Технические вопросы — не обязательно вопросы про то, как код писать. Обычно достаточно концептуального описания как решать ту или иную задачу.

Никакого тролинга, вам ниже уже писали схожее. Я говорил о том, что кроме кода есть масса критериев отбора.
Пожалуйста.
0 norlin 5 октября 2014 в 10:56 (комментарий был изменён)#↵↑
1. Откуда возьмётся «результат» до приёма человека на работу? Или предлагается оценивать некий готовый продукт с предыдущего места? А если там работало несколько десятков человек? А если наш кандидат исключительно серверный код писал?
2. Не «обычно», а «иногда». Иногда достаточно. А иногда не достаточно и нужно, чтобы человек знал, как задачу решить не «концептуально», а на конкретном языке.

Я говорил о том, что кроме кода есть масса критериев отбора.
Я это чуть ли не в каждом комменте твержу. Но не задавать вопросы по коду на собеседовании разработчика – это ОЧЕНЬ странный подход. Возможен, только когда вообще нет никого, способного оценить его ответы (и нет никого, кто мог бы погуглить подобные задачки с формальными ответами).
0 Zav 5 октября 2014 в 12:13#↵↑
1) Да, по предыдущим местам. По картине в целом. По отзывам о этом человеке с предыдущих мест.
2) Думаю что это только для стартапов актуально, в которых срочность превыше всего.

Я видел что ты пишешь в других комментариев, но, всё же, создается впечатление что это один из основных криериев. Можно тогда уж с такими вопросами давать человеку доступ к интернету и смотреть как быстро он найдет ответ :-)
0 norlin 5 октября 2014 в 13:04 (комментарий был изменён)#↵↑
Безусловно, при приёме на работу программиста, одним из важных критериев является знание кандидатом языка программирования. Вряд ли кто-то возьмёт на вакансию Javascript профессионала в C++, который JS первый раз видит.
0 Zav 5 октября 2014 в 13:07#↵↑
На удивление я подобное встречал далеко не один раз и далеко не в маленьких компаниях.
0 Zav 5 октября 2014 в 13:26#↵↑
Точнее, в маленьких я такого не встречал, только в крупных.
0 Aingis 4 октября 2014 в 13:34#↵↑
> Что делать, если нет хорошего кодстайла? Что делать, если проект только стартует и набирают команду?

Очевидно, надо почитать лучшие наработки и ввести кодстайл.

> Как вообще оценить навыки человека?

Можно позадавать вопросы, как работает то или иное, хорошо, если с учётом того, что используется или планируется использовать на проекте.

> А если у него нет кода, который может показать?

Можно и попросить написать код. Например, дать тестовое задание. Можно прямо в вакансии. Например, Яндекс так делал в некоторых вакансиях.
+1 norlin 4 октября 2014 в 13:42#↵↑
Очевидно, надо почитать лучшие наработки и ввести кодстайл.
Спасибо, Кэп. А кто будет читать наработки и вводить кодстайл, если нет спецов?

Можно позадавать вопросы, как работает то или иное
Так вопросы из поста именно на это нацелены! Просто вместо сложного кода реальных библиотек/фреймворков взяты искуственные примеры, чтоб лишнее не путалось.

Например, дать тестовое задание
По себе скажу, что тестовое задание делать очень лениво. Обычно проще пойти на другое собеседование. Надо очень вкусные условия предлагать, либо иметь большой поток желающих.
В первом случае, почему бы и не задать «каверзные» вопросы.
Во-втором, возможно, это вакансия Junior, куда чуть ли не любой кодер может подойти. Там да, имеет смысл не про Hoisting спрашивать, а давать задачки на общее мышление\любознательность и т.д.
+2 Aingis 4 октября 2014 в 13:50#↵↑
> А кто будет читать наработки и вводить кодстайл, если нет спецов?

Что значит: нет спецов? Вы как собираетесь проект делать и людей нанимать, не будучи способны даже оценить в данной области?

> Так вопросы из поста именно на это нацелены!

Вопросы из поста не дают желаемых результатов. Если человек не смог сформулировать как вы: «я точно знал что объект не измениться после вызова функции, но объяснить почему так и не смог,» это ещё ни о чём не говорит. Так и во всём. Достаточно более базовых вопросов.

Вам же надо оценить понимание человеком принципов работы, а не то, читал ли он 105 страницу спецификации ECMAscript. Это типичная ошибка, когда к собеседованию относятся как к какому-то экзамену. Хотя для работы это не нужно, а когда понадобится, ответ находится в интернете за минуту.

Специалистов и так видно по опыту, навряд ли вы найдёте супергероя, которому совсем нечего предъявить.
0 norlin 4 октября 2014 в 14:58#↵↑
Вы как собираетесь людей нанимать
Вот подобные вопросы и позволяют оценить кандидатов «в данной области».
Ещё раз, на всякий случай – не только такие вопросы. Но как часть оценки – очень полезны.
0 Zav 4 октября 2014 в 13:51#↵↑
> Спасибо, Кэп. А кто будет читать наработки и вводить кодстайл, если нет спецов?
А кто будет тогда контролировать ваши заковыристые задания? :-D

+1 vintage 4 октября 2014 в 14:41#↵↑
Это вопросы далеко не на 150к в месяц :-) Если к вам придёт действительно крутой специалист, то после непродолжительной беседы без единой строчки кода вы уже поймёте, что все эти вопросы нет смысла задавать. Нужны они лишь случае сомнений в компетентности вида «а не Junior ли это под Middle косит?»
0 norlin 4 октября 2014 в 15:00#↵↑
Именно! Я уже много раз тут написал – эти вопросы далеко не единственные. Да, возможна ситуация, когда окажется, что их нет смысла задавать (причём, с обеих концов – либо кандидат очевидно крутой, либо очевидно ничего не знает).

Нужны они лишь случае сомнений в компетентности
Всё так.
–1 jacob1237 6 октября 2014 в 21:06#↵↑
Позволю себе заметить, что также много времени на дебаг может отнять и вот этот код из Вашего последнего примера:

Logger = function(logFn) {

_logFn = logFn;

...
}

в котором объявляется по-сути глобальная переменная _logFn
+7 DenisZ 4 октября 2014 в 01:46#↵↑
м… ну, знать про function declaration все же надо
+19 AvrGavr 4 октября 2014 в 01:36#↵↑
У меня долгое время на при виде таких задач всплывала в голове фраза «Не надо писать странный код», но потом я понял для себя две вещи:
Частенько нам приходится работать с чужим, не всегда годным, кодом, и чем круче скилл «компилирования кода в голове» тем проще проходит этот процесс
Такие вопросы могут показать опыт человека, ибо если человек при виде странного кода сходу говорит, что тут не так и как это исправить — скорее всего он когда-то уже так напоролся и не поленился разобраться в вопросе
0 Drinker 5 октября 2014 в 17:18#↵↑
Буквально позавчера соискатель с готовностью отвечал на вопрос: что лучше Jquery или angular.
0 vintage 5 октября 2014 в 17:30#↵↑
Вы хотели сказать «что хуже»? :-)
+2 Drag13 5 октября 2014 в 18:36#↵↑
Очень интересно услышать аргументы :)
+8 mikenerevarin 4 октября 2014 в 01:28 (комментарий был изменён)#
> Функции объявленный при помощи function declaration имеют больший приоритет и понимаются выше var. Поэтому интерпретатор сначала выполнит function x() {};, а затем var x = 1;

Вообще-то интерпретатор выполнит сначала function x() {};, затем var x; и только потом x=1;
+3 AvrGavr 4 октября 2014 в 01:31#↵↑
Ну впринципе справедливо, хотя в контексте этой задачи большой роли не играет.
0 mark_ablov 4 октября 2014 в 07:13#↵↑
+1, тоже зацепился за этот момент.
Декларация переменных и их инициализация проходят отдельно хотя это одна синтаксическая конструкция.
В данной задаче может и не играет роли, но можно придумать такую, где играет.
+6 bolk 4 октября 2014 в 08:18#↵↑
Да пожалуйста:
(function() {
x = 1;

function x() {};
var x;

console.log(x);
})()

Тут ещё можно теперь спросить доступна ли «x» снаружи.
–5 mayorovp 4 октября 2014 в 12:23#↵↑
Вообще-то, var x будет «выполнен» одновременно с function x() {}. Слово «выполнен» я взял в кавычки, потому что объявления не выполняются.
+2 Burantino 4 октября 2014 в 13:04#↵↑
Вообще-то интерпретатор выполнит сначала function x() {};, затем var x; и только потом x=1;


Вообще-то интерпретатор _сначала_ выполнит var x; потом function x() {} и только потом x = 1.

Both function declaration and variable declarations are hoisted to the top of the containing scope. And function declaration takes precedence over variable declarations (but not over variable assignment)
+12 Zav 4 октября 2014 в 02:48#
Такие задачи решаются их недопущением в проекте.
Я обычно именно так и отвечаю на собеседованиях, с комментариями, как избежать такого написания.
Разбирать их смысла нет.
0 Zav 4 октября 2014 в 02:50#↵↑
Ну и ещё момент, что оно дебажится за минуту и переписывается по нормальному.
Заморачиваться заковыристой компиляцией в голове не стоит — лучше подумать о более высокоуровневых моментах.
+2 norlin 4 октября 2014 в 09:16#↵↑
Оно дебажится за минуту, если человек знаком с такими особенностями. Если же нет, он может кучу времени убить, пытаясь понять в чём проблема.
+4 zag2art 4 октября 2014 в 09:35 (комментарий был изменён)#↵↑
Допустим, человек потратит 3 часа на то, чтобы разобраться с этим в первый раз — в итоге разберется. Тогда весь смысл 10*n собеседований может свестись к найму человека, который вам эти 3 часа сэкономит. Чушь, на мой взгляд. Не лучше ли выяснить насколько человек целеустремленный и любознательный, насколько быстро перестраивается и какие у него вообще цели и ценности?

Хотя здесь конечно важны цели нанимателя тоже. Если вы рекрутинговое агенство и вам нужно продать человека поскорее, либо вам нужен кодер на 2 недели — тогда — да. Почему бы и нет.
–1 norlin 4 октября 2014 в 10:24 (комментарий был изменён)#↵↑
Не лучше ли выяснить насколько человек целеустремленный и любознательный
А одно другому не мешает.
Просто иногда нужен любознательный и целеустремлённый человек, который УЖЕ разобрался с большинством аспектов, а не только-только начинает осваивать JS.

Более того, если человек «целеустремленный и любознательный» – он наверняка потрудится заранее узнать особенности языка. Хотя бы, ради собеседования.

Честно, некоторые знают только $(...).show/.hide и $.ajax. И когда начинаешь спрашивать, оказывается, что не понимают ни ==/===, ни о замыканиях не могут рассказать/показать (хотя бы насчёт замыканий, надеюсь, вы согласитесь, что это часто используемая «фишка»)…
+1 Zav 4 октября 2014 в 12:43#↵↑
Ну на самом деле, как выше уже писали, человек может не знать ответов на вопросы, но узнает всё за 1 рабочий день. При этом он высококлассный специалист. И вот из-за какого-то глупого вопроса есть шанс его упустить. Это не круто.
Лучше смотреть предыдущие работы. Причем можно даже не код, а результат.
0 norlin 4 октября 2014 в 12:47#↵↑
Ниже ответил – никто не говорит, что подобные задачки это единственный критерий.
0 Zav 4 октября 2014 в 12:39#↵↑
Не, ну я согласен на какие-либо базовые вопросы — замыкания, наследования и т.п., но вот всякие «хитрые» случаи вообще ничего не показывают.
Да и даже спрашивая что-то совсем базовое, можно сильно ошибиться, если давно разрабатываешь на значительно более высоком уровне, чем решение проблем с замыканиями, и просто «подзабыл» данный момент, но найти ответ займет пару минут.
+2 norlin 4 октября 2014 в 12:46#↵↑
Это тоже может иметь значение. Бывают задачи, где надо работать именно с «низкоуровневыми» вещами.

Никто не говорит, что это единственный критерий. Просто подобные вопросы помогают оценить реальный опыт. Если человек не знает, или не помнит – можно оценить хотя бы его рассуждения, настойчивость\целеутстремлённость и всё-такое.
Один только лишь увидев подобное сразу скажет «нет, не знаю, давайте дальше».
А другой попытается понять, даже если не встречал такую конструкцию раньше.

Первый на данном вопросе пролетит полностью, а второй получит плюс, даже если ответит лишь с помощьбю наводящих вопросов. Или даже если не ответит, но покажет, что умеет логично мыслить.
–3 Zav 4 октября 2014 в 12:48#↵↑
Низкоуровневые вещи != гавнокод :-)
Те ситуации, что описаны в посте, должны избегаться не зависимо от уровня.
0 norlin 4 октября 2014 в 12:55#↵↑
Вопросы из поста – это тестовые задания. Искуственные куски кода, специально написанные, чтобы проверить, знает ли человек тот или иной аспект языка. Речь про собеседование, а не про «хороший и качественный js в проекте».
+1 Zav 4 октября 2014 в 13:02#↵↑
Это плохие тестовые задания. Они тебе покажут ничего.
Можно научиться проходить такие «задачи» даже не понимая сути вещей.
Я обучал нескольких ребят проходить интервью ещё когда они не были даже junior разработчиками. И именно благодаря подходу выше их брали, уверенными что человек всё знает, когда это было не так. Тем не менее на работе быстро изучали что надо, и это не было замечено никак.
Они все, в принципе, схожи, и ходят вокруг одних и тех же принципов.
0 norlin 4 октября 2014 в 13:04 (комментарий был изменён)#↵↑
Я уже сказал выше, что они мне показывают. Зачем вы пытаетесь доказать обратное, если оно мне уже помогало на собеседованиях?

Я обучал нескольких ребят проходить интервью ещё когда они не были даже junior разработчиками.
А вот это как раз опровергает ваши доводы. Если человек, освоивший хотя бы такие «плохие» тестовые примеры уже может работать с этим языком – значит эти примеры как раз и проверяют в той или иной степени знание языка.
+4 Zav 4 октября 2014 в 13:07#↵↑
Тесты на IQ отражают способность человека проходить тесты на IQ и не более. Тут тоже самое.
0 norlin 4 октября 2014 в 13:11 (комментарий был изменён)#↵↑
Разница в том, что если человек поймёт замыкания, приведение типов, function declaration, hoisting и т.д. – он по-определению будет знать JS.

Возможно, у него не будет реального опыта – но это уточняется уже другими средствами (резюме, примеры работ, тестовые задания, задачки на архитектурные вещи и т.д.)
0 Zav 4 октября 2014 в 13:15#↵↑
Да ладно тебе.
Это всё «понимается» за день изучения. Какие тут реальные знания то?
Понимание этого всего не спасает от плохого кода, ошибок такого рода и т.п.

Неужели 1 день изучения темы является критерием опытного специалиста? Ну это печально тогда.

Могу предложить вариант такой: спрашивать у человека какую библиотеку он использует, потом открывать её код, и просить объяснить как она устроена и работает. Вот это может сработать ещё как-то.
+2 norlin 4 октября 2014 в 13:17 (комментарий был изменён)#↵↑
Более того, если найдётся человек, впервые увидевший JS, который за один день поймёт замыкания – уверен, любая команда будет счастлива заполучить его себе (как Junior, который с такими-то способностями уже через месяц-два станет полноценным разработчиком).

Понимание этого всего не спасает от плохого кода, ошибок такого рода и т.п.
Эээ… Значит, это было не понимание, а тупое заучивание шаблонов.
+1 Zav 4 октября 2014 в 13:20#↵↑
Тут согласен :-) Но момент в том, что можно упустить достаточно хорошего специалиста, не разбиравшегося глубоко в данных вопросах, либо который просто забыл как правильно, но при доступе к интернету даст быстрый ответ.
0 Zav 4 октября 2014 в 13:21#↵↑
Так я про это и пишу, ура!
0 norlin 4 октября 2014 в 13:31 (комментарий был изменён)#↵↑
Я немного не то имел в виду про «заучивание». Если человек тупо заучил подобные шаблоны – это не спасёт его от ошибок. Если же он реально понимает такие моменты – то спасёт. В худшем случае, это будет не ошибка, которую надо дебажить, а «опечатка», исправленная за минуту.
+1 Zav 4 октября 2014 в 13:35#↵↑
Я говорю о заучивании без понимания. Собеседования, о которых говоришь, могут быть пройдены заучиванием без понимания.
Вспомни школьных зубрил, которые преподавателю отвечают на ура, а ты, со своим глубоким пониманием, иногда, плаваешь. В этом и суть.
0 norlin 4 октября 2014 в 13:46 (комментарий был изменён)#↵↑
Я уже несколько раз тут писал, что подобные вопросы – это далеко не всё собеседование. Лишь его часть. Да, они в какой-то степени могут быть пройдены заучиванием. И то, код-то в таких вопросах может быть разным.

В школе как раз и заметил, что если понимаешь – то проблем ответить никаких нет. Пусть даже своими словами. А если не понимаешь, но считаешь, что знаешь лучше всех – тогда да, «зубрилы» будут впереди.
+1 Zav 4 октября 2014 в 13:52#↵↑
Если понимаешь — то всегда есть сомнения.
Если не понимаешь, то сомнений нет.
Тут почти как с религией.
–1 norlin 4 октября 2014 в 15:06#↵↑
Программирование почти как религия. Докатились… Спасибо, буду теперь знать, как отсеивать подобных кандидатов, если снова придётся кого-то собеседовать.
+1 Zav 4 октября 2014 в 15:09 (комментарий был изменён)#↵↑
Очень здорово, наверное, слова собеседника передёргивать.
Обрати внимание на контекст, пожалуйста.
0 vintage 4 октября 2014 в 14:52#↵↑
Очень интересно в чём именно заключалось обучение.
+4 alemiks 4 октября 2014 в 12:13#↵↑
Если примеры для задач надерганы из реальных проектов этой конторы то, может, стоит прекратить собеседование и поискать место, где меньше говнокода (хотя бы на собеседовании его нет)?
+3 Zav 4 октября 2014 в 12:46#↵↑
Именно так, + тебе.

Но, на самом деле, это не очень хороший подход. Тебя могут нанимать именно что бы исправить ситуацию, а ты поводишь носом и скажешь «Фу, фу, фу».
Хотя при таком подходе было бы как раз правильно спрашивать как это переоформить и как избежать подобных проблем :-)
Тут проблема в том, что собеседование должен проводить реальный спец, а его может и не быть. Точнее, если он есть, то как он сам всё это допустил? :-)
–2 genbit 4 октября 2014 в 04:55 (комментарий был изменён)#
Мне больше нравятся задачи на собеседовании, которые помогают понять как человек будет решать проблемы, с которыми он будет сталкиваться на этой работе.
Пример «реализовать элемент прогресс бара 200px, заполняется за 5 сек», последущий вопрос «реализовать кнопку, добавляющую на страницу элемент прогресс бара, который начинает анимироваться сразу как добавлен», и последующее: «модифицировать этот код так, чтобы ново-добавленый прогресс бар, начинал анимацию, только когда закончиться анимация предыдущего»
Задача приближенная к боевой, и раскрывает разные стороны работы javascript программиста.
+3 Zav 4 октября 2014 в 05:09#↵↑
Лучше посмотреть на предыдущие работы :-)
Никакие задания всё равно не покажут как будет человек на данном месте работать.
0 genbit 4 октября 2014 в 06:16#↵↑
Ну это я за себя говорю, когда я собеседовался, мне дали такую задачку.
А как посмотреть на предыдущие работы? Если весь код проприетарный?
+1 Zav 4 октября 2014 в 06:31#↵↑
Ну прямо весь-весь код редко у кого бывает под НДА, хотя бы потому, что у НДА, обычно, ограничение по времени ~3 года.
Если уж прям всё так плохо, можно продемонстрировать не ключевой код, без передачи (лично с планшета, например) — за такое никто не накажет.
0 Zibx 4 октября 2014 в 05:08#
Про «Контекст выполнения». Это поведение хрома. Там log нужен верный this. В firefox работает и тот пример что надо «исправлять».
0 rock 4 октября 2014 в 05:38#↵↑
В огнелисе поведение аналогично хрому. Работает в IE, фаербаге (может его имели в виду?) и на ноде.
0 Zav 4 октября 2014 в 05:42 (комментарий был изменён)#↵↑
Нет, он всё правильно сказал.
В FF (32, win 8) пример работает «как есть» без всяких ошибок.
Прошу прощения, действительно только в фаербаге.
0 rock 4 октября 2014 в 05:50#↵↑
Актуальный FF33:

FF35:

+1 Zibx 4 октября 2014 в 14:00#↵↑
Фаербаг, да. Нода — тот же V8. С фаербагом как-то забываешь что это не нативный дебаггер. А когда натянешь на него ещё и AceBug, то это становится единственной причиной, по которой я окончательно не перешел на хром для разработки.
+5 mark_ablov 4 октября 2014 в 07:21#
> Наверное все знают что все объекты передаются в javascript по ссылке
Ответ-то простой — pass-by-reference не существеует в javascript'e.
Передаётся значение — «указатель» на объект, но не ссылка. (если исходить из тепрминов C/C++).
0 AvrGavr 4 октября 2014 в 10:09#↵↑
Я мыслил именно в этом направлении, когда сам эту задачку решал :) Но всё равно можно запутаться, если не знать что аргументы становятся локальными переменными ф-ции.
+1 mark_ablov 4 октября 2014 в 10:27#↵↑
А в каком языка не используя pass-by-reference это не так?
Не нужно путать причину со следствием.
+4 Nesvet 4 октября 2014 в 13:11#↵↑
Блин, это не совсем правильно. Переменная-аргумент obj внутри функции локальна, но суть в том, что ей присваивают указатель на новый объект — {a: 2}.

Если сделать так:
var obj = {
a: 1
};

(function(obj) {
obj.a = 2;
})(obj);

console.log(obj.a);//, то здесь будет «2».
+1 zerkms 4 октября 2014 в 12:13 (комментарий был изменён)#↵↑
Передаётся значение — «указатель» на объект, но не ссылка. (если исходить из тепрминов C/C++).


На указатель оно ещё меньше похоже.

Если пытаться быть до конца точным, то использованная в JS техника называется call by sharing
0 mayorovp 4 октября 2014 в 12:28#↵↑
Нет, именно на указатель оно и похоже. Возможно, вам мешает провести аналогию отсутствие оператора разыменования * — зато аналогия между . в javascript и -> в С/С++ — полная.
+1 zerkms 4 октября 2014 в 12:32#↵↑
Так точно, именно отсутствие оператора `*` и мешает. Но, слава богу, у этой реализации есть настоящее имя, которое позволяет нам использовать именно его, избегая вещей вроде

«типа ссылки, но не можем изменять весь объект, только мутировать»
или
«типа указателя, но нет оператора его разыменования»
0 mayorovp 4 октября 2014 в 12:38#↵↑
И это настоящее имя называется «передача по значению»…
+1 zerkms 4 октября 2014 в 12:44#↵↑
Лично мне больше нравится объяснение из википедии:

The description «call-by-value where the value is a reference» is common (but should not be understood as being call-by-reference); another term is call-by-sharing.
+1 mayorovp 4 октября 2014 в 12:46#↵↑
Давайте на нем и остановимся.
0 zerkms 4 октября 2014 в 12:36#↵↑
PS: и, да, я согласен, что оператор `.` в JS и `->` в С++ ведут себя похоже. Мой поинт был лишь о переменной и её поведении, а не об операторах к ней применяемым.
+1 northbear 5 октября 2014 в 13:24#↵↑
Это именно pass-by-reference, но на уровне абстракции языка Javascript этого понятия не существует. Для понимания, достаточно разобраться в том, что такое boxed и unboxed types.

Вообще, на github'е есть совершенно замечательная статья Cпенсера Типпинга: Js in 10 minutes. Там отлично разбираются все «приколы» js'а и способы их решения. После нее такие тесты проходятся на ура.

Как говорится, must have для любого js-ера…
0 mayorovp 5 октября 2014 в 13:38#↵↑
function foo(arg) { arg = 5; }

var bar = 10;
foo(bar);

Если бы это была передача по ссылке, то переменная bar стала бы равна 5.
0 northbear 5 октября 2014 в 13:47#↵↑
Прочитайте всё-таки, что такое boxed/unboxed types…
0 mayorovp 5 октября 2014 в 13:55#↵↑
Спасибо, я знаю что такой упакованные и распакованные типы. Но от упаковки ничего не изменится:
function foo(arg) { arg = 5; }

var bar = new Number(10);
foo(bar);
bar все равно не стал равен 5.

function foo(arg) { arg = {value: 5}; }

var bar = {value: 10};
foo(bar);
и даже вот так переменная не изменилась. Такое поведение — это и есть передача по значению.

Если же вы решите сделать так:
function foo(arg) { arg.value = 5; }

var bar = {value: 10};
foo(bar);
то я вам скажу, что изменилось содержимое объекта, но переменная все еще продолжает указывать на тот же самый объект. Это все равно передача по значению.
0 northbear 5 октября 2014 в 14:04#↵↑
Дык, вопрос в том, что является значением в первом и во втором случае… То что js «распаковывает» переменные базовых типов при передаче в качестве параметра в функцию, это тоже один из «приколов» js'а…
+1 northbear 5 октября 2014 в 14:19 (комментарий был изменён)#↵↑
В общем, про распаковку я фигню написал, каюсь. Что происходит хорошо видно в этом коде:

function foo(arg) {
arg.gotcha = "bye-bye"
arg = 5;
}

var bar = new Number(10);
bar.gotcha = "hello";
foo(bar);

console.log(bar); // => 10
console.log(bar.gotcha); // => "bye-bye"

+1 monolithed 5 октября 2014 в 21:37#↵↑
Можно так исхитриться:

function foo(object, value) {
object.valueOf = function () {
return value;
};
}

var bar = new Number(0);
foo(bar, 100);

bar + 1; // 101



0 mayorovp 5 октября 2014 в 21:39#↵↑
Забавно, но это просто поведение оператора сложения, но никак не передача по ссылке :)
0 kyrylo 4 октября 2014 в 11:25#
Кажется, для последнего примера достаточно и такого кода (убрал ненужное присвоение):

Logger = function(logFn) {
this.log = function(message) {
logFn(new Date() + ": " + message);
};
}


Если я правильно разобрался, то это лишь касается только встроенных функций, так как такие функции ожидают, что this равен window (или, к примеру, console). Достаточно обернуть встроеную функцию в свою, чтобы это исправить. Например, такой аргумент сработает.

console.myLog = function(message) { console.log(message) };
var logger2 = new Logger(console.myLog);

logger2.log("Hi!");
logger2.log("Wazzup?");

// Sat Oct 04 2014 09:30:04 GMT+0300 (EEST): Hi!
// Sat Oct 04 2014 09:30:04 GMT+0300 (EEST): Wazzup?


Однако оба таких решения не самые изящные, так как нам везде придётся использовать либо bind(), либо function. Можно пойти другим путём и байндить встроенные функции к window внутри тела log. Функция isNative взята из внешних источников.

var Logger = function(logFn) {
if (isNative(logFn)) {
this.log = function(message) {
logFn.bind(window)(new Date() + ": " + message);
};
} else {
this.log = function(message) {
logFn(new Date() + ": " + message);
};
}
}

var logger3 = new Logger(alert);

logger3.log("Hi!");
logger3.log("Wazzup?");


Однако такой трюк с console не пройдёт (и другими встроенными объектами, содержащими встроенные своёства наподобие console.log. Я не придумал, как это обойти.
0 Dolios 4 октября 2014 в 11:41#↵↑
Однако оба таких решения не самые изящные, так как нам везде придётся использовать либо bind(), либо function.

А чем вам bind не изящный?

Однако такой трюк с console не пройдёт (и другими встроенными объектами, содержащими встроенные своёства наподобие console.log. Я не придумал, как это обойти.

Передавать в логгер вместе с функцией скоп вызова?

Я уж молчу о том, что пример хреновый, хотя бы потому, что console.log умеет несколько аргументов, а логгер в примере — нет.
0 kyrylo 4 октября 2014 в 12:02#↵↑
А чем вам bind не изящный?


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

Передавать в логгер вместе с функцией скоп вызова?


Тоже вариант. Но, по-видимому, лучше использовать bind(), так как с ним знакомо несравнимо большее количество людей, чем с Logger (смысл-то остаётся такой же).
0 Dolios 4 октября 2014 в 12:52#↵↑
Когда человек, который хочет инициализировать объект Logger увидит такой код, ему придётся потратить время, чтобы разобраться, как работает конструктор, что неоправданно усложняет код. Я попытался скрыть детали реализации. :)

Не очень понял, о чем вы. Имхо, любой джуниор, передавая куда-то функцию, должен позаботиться о корректном скопе вызова, если для передаваемой функции это критично (что, в общем случае, не всегда так).
+1 mayorovp 4 октября 2014 в 12:31#↵↑
Если я правильно разобрался, то это лишь касается только встроенных функций, так как такие функции ожидают, что this равен window (или, к примеру, console). Достаточно обернуть встроеную функцию в свою, чтобы это исправить. Например, такой аргумент сработает.
Неверно. Любой метод ожидает корректного this, не только встроенный.

var obj = {
value: 5,
foo: function() { console.log(value); }
};

obj.foo(); // 5
var foo = obj.foo();
foo(); // undefined
0 kyrylo 4 октября 2014 в 12:53#↵↑
Подозреваю, что имелся в виду этот код.

var obj = {
value: 5,
foo: function() { console.log(this.value); } // [исправлено]
};

obj.foo(); // 5
var foo = obj.foo; // [исправлено]
foo(); // undefined


Отличный пример, спасибо! Стало понятнее. Можно упростить до такого:

var log = console.log;
log('Hello'); // TypeError: Illegal invocation

log.bind(console)('World'); // => World


стоит указать в статье, что пример с TypeError предполагает то, что он будет запускаться в Chrome.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#2 dyvniy » Чт, 29 мая 2014, 15:55:20

Processing.js
http://www.gamedev.ru/code/forum/?id=189516
http://processing.org/reference/
http://processing.org/examples/star.html

Добавлено спустя 2 минуты 46 секунд:
Рекурсивное деревце
http://nemehanika.ru/show/tree/
<script src="processing.js" type="text/javascript"></script>
<script type="text/javascript">
// convenience function to get the id attribute of generated sketch html element
function getProcessingSketchId () { return 'Tree'; }
</script>

v8 standalone
http://stackoverflow.com/questions/1802478/running-v8-javascript-engine-standalone
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#3 dyvniy » Вт, 15 июля 2014, 08:31:58

Можно сразу видеть результат.
Пример - задержка от пинга.
http://jsfiddle.net/Pvs5r/

ещё
http://www.wisdomweb.ru/editor/wweditor.php?fname=html_but
Вложения
js_ping.png
js_ping.png (5.9 КБ) 1100 просмотров
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#4 dyvniy » Пт, 25 июля 2014, 15:51:16

Чтоб не тормозил
http://habrahabr.ru/post/136360/
Спойлер
Оптимизация JavaScript для ускорения загрузки веб-страниц
JavaScript*
Инженер из компании Google, автор трёх книг по веб-производительности и оптимизации, Стив Содерс (Steve Souders) опубликовал презентацию "JavaScript Perfomance" о том, какие методы нужно применять, чтобы скрипты меньше тормозили загрузку страниц.

По статистике WebPagetest, блокировка загрузки файлов .js на сайтах из Alexa Top 100 снижает среднее по медиане время загрузки страницы c 3,65 с до 2,487 с, то есть на 31%. Если вы видите медленную загрузку веб-страниц и хотите улучшить этот показатель, то, по мнению Стива Содерса, первым делом нужно посмотреть на JavaScript.

В качестве примера оптимизации Стив Содерс приводит сниппет Google Analytics.

var ga = document.createElement(‘script’);
ga.type = ‘text/javascript’;
ga.async = true;
ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;
var s = document.getElementsByTagName(‘script’)[0];
s.parentNode.insertBefore(ga, s);

Особое внимание он обращает на строчку

ga.async = true;

Этот параметр означает, что скрипт ga.js не будет блокировать исполнение других асинхронных скриптов.

Ещё один момент — инструкция insertBefore. Оказывается, некоторые браузеры блокируют выполнение скриптов, если ещё не загружен скрипт с инструкцией insertBefore. Естественно, это замедляет загрузку страницы. Другими словами, такие браузеры будут ждать, пока на странице не загрузится модуль Google Analytics, и до этого момента все остальные скрипты блокируются. Параметр ga.async = true исправляет ситуацию во многих современных браузерах. Но не во всех.

Стив Содерс сделал специальную страничку, чтобы выявить те версии браузеров, которые игнорируют инструкцию ga.async = true при наличии insertBefore. Он собрал статистику с 60+ различных браузеров — как видно в таблице по ссылке, главным «нарушителем» является браузер Opera. Запустить тест и провериться можно здесь.

В презентации "JavaScript Perfomance" Стив Содерс говорит о модуле для ускорения загрузки скриптов ControlJS, а также об использовании localStorage в качестве кэша.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#5 dyvniy » Пт, 28 ноября 2014, 18:24:20

Невидимый код
http://habrahabr.ru/post/243351/
Спойлер
Код, которого нет из песочницы
Кодобред*, JavaScript*, Веб-разработка*, Ненормальное программирование*
Привет, хабравчане!

Около года назад Хабр захлестнула волна постов на тему "%string% в N строчек на JavaScript". Уже и не вспомню, чем все закончилось, но началось все с «Excel в 30 строк». Следом появилось много и других интересных вариаций на эту тему, даже игра в ноль строк на JS, но это уже совсем другая история…

Как я ни старался придумать что-то еще более компактное — ничего не выходило. Тогда было принято решение посмотреть на проблему под другим углом. Примерно в этот момент в голове промелькнул вопрос: а можно ли «сколлапсировать» код так, чтобы его не было вообще? И тут мне позвонил Дэвид Блейн.

Я попробовал добавить немного магии и вот что у меня получилось.

image

«Исчезатор» кода

Задача написать код, которого… как бы нет. Еще он должен уметь что-то делать. Очевидно, что какие-либо манипуляции нужно сопроводить некоей функцией, которая бы могла интерпретировать эти манипуляции, а поэтому скрыть код вообще, увы, не выйдет, но сократить последний до пары-тройки строчек — запросто.

Многие знают или слышали, что в компьютерной типографике существуют непечатные символы, т.е. фактически невидимые. Причем это не какой-то баг или фишка, а вполне нормальное поведение — быть невидимыми. В настоящий момент одной из общепринятых и стандартизированных кодировок текста является UTF-8, она используется практически на любом современном сайте. В ней ценно и то, что там присутствует целая куча невидимых символов! Например, один из них — Zero Width Space (U+200B). Вот он: "​". Видите? Нет? А он есть.

Метод Дэвида Блейна

Для желающих потрогать руками привожу ссылку на пример годичной давности: рабочее демо смотреть бесплатно онлайн. Уже потом, спустя несколько месяцев после заметки в песочнице Хабра, я случайно набрел на пост, где просматривалась эта идея (способ номер три), но без изюминки.

В моей версии кодирование производилось наипримитивнейшим образом. Минус — сильно возрастает объем файла, плюс — нужно всего два символа для кодирования. Выглядело примерно так:
var code = '1101101111110111111111111111110101101101111101111';

Спустя довольно длительное время, я вернулся к этой теме в рамках одного проекта, которым занимаюсь. Была предпринята попытка пойти дальше и начал с того, что теперь каждый символ кодируется не единицами и нулями, а четырьмя символами:
"f".charCodeAt(0).toString(16);
// "66"

//Таким образом код символа "f" - 0x0066
String.fromCharCode("0x0066");
// "f"

В итоге, имея набор из 16 символов, можно сократить избыток лишнего кода:
var Symbols = ["й","ц","у","к","е","н","г","ш","щ","з","х","ъ","ф","ы","в","а"];

//Теперь можно закодировать символ "f":
var bar = invisibleJS("f");
// bar = "ййгг";

Увеличение объема, занимаемого кодом в данном примере снизилось до 4х (4 символа, чтобы закодировать один), но по идее, если не нужен русский язык и/или какие-то другие не латинские символы, то можно добиться и 2х.

Примеры в студию

Пускай будет такой код:
alert("Hello world!");

После скармливания кода обфускатору (приводить и разбирать код не буду, в нем нет ничего интересного), на выходе получается что-то вроде:
var helloworld = "⁡⁡‫‌⁡⁡‫⁡⁡‫‪⁡⁡‬‍⁡⁡‬‏⁡⁡‍‭⁡⁡‍‍⁡⁡‏‭⁡⁡‫‪⁡⁡‫⁡⁡‫⁡⁡‫⁡⁡‍⁡⁡⁡‬‬⁡⁡‫⁡⁡‬‍⁡⁡‫⁡⁡‫‏⁡⁡‍‌⁡⁡‍‍⁡⁡‍‮";

Обратите внимание на то, что точка с запятой находится внутри кавычек, хотя на самом деле это не так (можно проверить почти в любом текстовом редакторе, например Sublime). С одной стороны, это добавляет +5 к обфускации, вводит в заблуждение и грозит легким brain-fuck'ом, с другой — «правильный» редактор не будет применять символы влияющие на направление текста (слева-направо, справа-налево).

Вот так выглядит в результате функция декодирования:
var revealJS = function(s){return s.match(/(.{4})/g).map(function(b){return b.split('').map(function(i){return Array.apply(null,{length:10}).map(Number.call,Number).concat('abcdef'.split(''))['⁡‌‍‎‏‪‫‬‭‮'.split('').indexOf(i)]})}).map(function(c){return String.fromCharCode(0+"x"+c.join(''))}).join('')}

Более чем уверен, что код мог быть лучше, меньше и элегантнее, но такой задачи не стоит в данном посте. Обращаю внимание, что в конце строки код опять идет справа-налево. В общем-то этот нюанс можно исключить, если подобрать немного другие невидимые символы.

Теперь можно «проявлять» невидимый код:
var helloworld = "⁡⁡‫‌⁡⁡‫⁡⁡‫‪⁡⁡‬‍⁡⁡‬‏⁡⁡‍‭⁡⁡‍‍⁡⁡‏‭⁡⁡‫‪⁡⁡‫⁡⁡‫⁡⁡‫⁡⁡‍⁡⁡⁡‬‬⁡⁡‫⁡⁡‬‍⁡⁡‫⁡⁡‫‏⁡⁡‍‌⁡⁡‍‍⁡⁡‍‮";

revealJS(helloworld);
// "alert("Hello world!")"

eval(revealJS(helloworld));
// Оп!

Можно прямо отсюда скопировать в консоль или посмотреть здесь.

(Приведенный в качестве примера код «проявлятора» заточен конкретно под определенные символы, использующиеся в функции «исчезатора». Меняя эти символы местами и/или используя другие, кол-во вариантов «кодовой таблицы» взлетают далеко в бесконечность.)

У всего этого есть один большой минус: можно подглядеть выполненный с помощью eval() код. Более того, консоль даже укажет файл/строчку откуда этот код запущен:


Можно исправить это недоразумение. Если использовать все четыре символа для кодирования (о чем я говорил выше), то появляется возможность обфускации внутри обфускации. Xzibit в восторге:
// Брюки превращаются...
alert("Hello world!");
// Превращаются...
window["alert"]("Hello world!");
// Брюки...
window[revealJS("⁡⁡‫‌⁡⁡‫⁡⁡‫‪⁡⁡‬‍⁡⁡‬‏")](revealJS("⁡⁡‏‭⁡⁡‫‪⁡⁡‫⁡⁡‫⁡⁡‫⁡⁡‍⁡⁡⁡‬‬⁡⁡‫⁡⁡‬‍⁡⁡‫⁡⁡‫‏⁡⁡‍‌"))
// ...превращаются в невидимый код:
"⁡⁡‬‬⁡⁡‫‮⁡⁡‫⁡⁡‫‏⁡⁡‫⁡⁡‬‬⁡⁡‪⁡⁡‫‌⁡⁡‬‎⁡⁡‫⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‪⁡⁡‍‭⁡⁡‫‌⁡⁡‬‎⁡⁡‫⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‍‮"

Смотреть можно здесь. Кстати, никто не мешает обфусцировать код хоть трижды, хоть четырежды.

Теперь результирующий код выглядит так:


Уже лучше, но можно сделать еще кое-что. Вначале статьи я обозначил задачу скрыть код так, будто его нет. Сейчас же, можно просто открыть консоль и все сразу видно, что нехорошо. Устранить этот нюанс оказалось довольно просто: вместо eval() надо использовать <script></script>:
var script = document.createElement("script");
script.innerHTML = revealJS("⁡⁡‬‬⁡⁡‫‮⁡⁡‫⁡⁡‫‏⁡⁡‫⁡⁡‬‬⁡⁡‪⁡⁡‬‍⁡⁡‫‪⁡⁡‬‫⁡⁡‫‪⁡⁡‫‌⁡⁡‫⁡⁡‏⁡⁡‪‎⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‪⁡⁡‍‭⁡⁡‬‍⁡⁡‫‪⁡⁡‬‫⁡⁡‫‪⁡⁡‫‌⁡⁡‫⁡⁡‏⁡⁡‪‎⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‍‮");
document.getElementsByTagName('body')[0].appendChild(script);
// А потом сразу же удаляем тэг, чтобы не маячил перед глазами
document.getElementsByTagName('body')[0].removeChild(script);

К сожалению, при выполнении этого кода на jsFiddle код все равно проявляется. Есть подозрение, что это каким-то образом связано с тем, что код в окне JavaScript так же оборачивается в eval() или тот же <script></script>. При тестах на локальном проекте, где нет «чудес», все работает как надо, выполняемая функция себя не проявляет:
image

Области применения

1. For fun.
2. Средство обфускации кода.
3. Использование совместно с другими способами минификации/обфускации кода. Например Google Closure Compiler или UglifyJS.
4. Возможность скрытного общения на открытых площадках.
5. «Спящие» скрипты, «закладки» в статьях, сообщениях на форумах, досках объявлений, в контекстной рекламе, да вообще где угодно, где дают что-нибудь написать и это потом попадает в браузеры пользователей.

С последними двумя пунктами не все так однозначно, но не мог их не упомянуть. Немного раскрою мысль. При беглом просмотре, было обнаружено, что, например, Gmail и Яндекс.Почта не удаляют такие символы. Некоторые трансформируются в вид &zwj; &#8234; &lrm;, но часть остается таки невидимой. Думаю, что в почтовых клиентах ситуация аналогичная (я проверил Thunderbird) — ничего не видно. Значит в письме можно послать скрытое сообщение, которое при «визуальном осмотре» не выдаст себя никак и при всем при этом даже в случае обнаружения непонятных скрытых символов расшифровать это сообщение сможет только тот, у кого есть алгоритм дешифрации (который, в общем-то, можно хранить в голове и написать код прямо в консоли браузера):
Привет, как дела⁡⁡‍⁡⁡‍⁡⁡‏‏‌⁡‏‎‪⁡‏‎‎⁡‏‎⁡‏‎‏⁡‏‎⁡‏‏⁡⁡‍⁡⁡‏‎‍⁡⁡‍⁡⁡‏‎⁡‏‏⁡‏‏‍⁡‏‏⁡⁡‍⁡⁡‍⁡⁡‏‎⁡‏‏⁡⁡‏‎‭⁡‏‏‪⁡‏‎⁡‏‎‏⁡‏‎‭⁡⁡‍⁡⁡‏‎⁡‏‎‏⁡‏‎‭⁡‏‎?

А на самом деле (надо применить ф-цию revealJS() к той части, что находится между буквой «а» и знаком вопроса):
Привет как дела/*, сегодня в пять, приходи один*/?

image

Таким образом есть возможность скрытного общения на открытых площадках. При этом никто ничего и не заподозрит. (Разве что целенаправлено будут искать, но это другой разговор). В общем, одно из главных преимуществ (а может и единственное) заключается в том, что содержание проходит «визуальный контроль» (но и тут не все так гладко: можно сменить кодировку и все обнажится). Это как человек-невидимка и система видеонаблюдения. Кто знает, может быть весь интернет уже давно напичкан такими сообщениями? :)

Что касается спрятанных скриптов, то тут все очевидно: если в ваш браузер каким-либо образом попадет вредоносный js-код, содержащий «проявлятор» и «запускатор» (например, многие подгружают библиотеки извне, взять тот же самый jQuery, который не так давно взламывали, или какой-нибудь распространенный плагин, например AdBlock), то спрятанный на странице код с определенной степенью вероятности будет запущен. То есть в данном случае схема такая: множество разных «векторов», каждый из которых направлен по-своему и один единый «активатор», который совсем крохотный.

Спасибо за внимание.

П.С. Маленький «ништячок»: если в скрипте вначале строки поставить символ U+202E (Right-To-Left Override) в кавычках, то будет веселье. Работоспособность кода при этом сохраняется:

"‮";var revealJS = function(s){return s.match(/(.{4})/g).map(function(b){return b.split('').map(function(i){return Array.apply(null,{length:10}).map(Number.call,Number).concat('abcdef'.split(''))['⁡‌‍‎‏‪‫‬‭‮'.split('').indexOf(i)]})}).map(function(c){return String.fromCharCode(0+"x"+c.join(''))}).join('')}
javascript, invisiblejs, магия, обфускация
— 3984
46NikitaKA 24,5
Похожие публикации
Espruino Pico: миниатюрная плата разработчика с JavaScript поможет быстро освоиться в мире электроники 20 ноября в 20:27
Краткий конспект по языку JavaScript 17 ноября в 14:48
Алгоритмы и решения при разработке движка JavaScript на C# 17 ноября в 14:41
Well.js – еще один подход к модульной разработке на JavaScript 17 ноября в 14:05
Изоморфные JavaScript-приложения с Catberry.js 12 ноября в 08:54
Продвинутое использование объектов в JavaScript 24 октября в 18:18
Изучаем Javascript перебирая косточки Backbone.js 23 октября в 15:30
Как я завел дружбу с асинхронностью в JavaScript 21 октября в 22:14
PassGenJS. Генерируем пароли в Javascript с указанием надёжности 20 октября в 11:12
Эквалайзер на JavaScript 19 октября в 08:43
Комментарии (7) отслеживать новые: в почте в трекере

0 bolk28 ноября 2014 в 16:45#
А ещё можно использовать этот символ для стеганографии: http://bolknote.ru/2012/01/23/~3556.
0 NikitaKA28 ноября 2014 в 16:53#↵↑
Таких символов много, но есть нюанс. Он заключается в том, что многие символы все равно отображаются в том или ином редакторе. Подобрать «правильный» набор — это не такая уж и простая задача.
0 bolk28 ноября 2014 в 16:56#↵↑
В данном случая я думал о браузерах — можно «подписывать» текст в закрытых системах, а потом смотреть кто стырил.
0 NikitaKA28 ноября 2014 в 16:59#↵↑
Приношу извинения, пробежался по ссылке очень быстро в поисках предложенного вами символа и не уловил основной идеи поста. На самом очень интересное предложение, спасибо за идею!
0 Magistr_AVSH28 ноября 2014 в 17:36#
Спасибо, очень интересно, сам копаю с разной периодичностью тему скрытия javascript'a от отладчиков (не потому что алгоритмы прямо такие особые или какой-нибудь вредонос, а просто открывать исходники всяким кулцхакерам в моем случае не хочется), но далеко увы не ушел. Обычно если спросить на эту тему людей — все скажут в один голос — нельзя ничего скрыть. Но это конечно не совсем правда и скрыть можно, правда с невеликой эффективностью.
Первая проблема — это скрыть от отладчика, ибо из исходников код убрать не представляет никакой сложности.
Ну а вторая проблема — это не дать влезать в процесс исполнения кода. Потому что есть простая хитрость — берем и прерываем выполнения кода в отладчике. И все, весь код сразу как на ладони, при условии что какой-то скрипт выполняется постоянно (у меня — отрисовка графики).
0 NikitaKA28 ноября 2014 в 17:53#↵↑
Действительно, самая большая проблема — отладчик, он позволяет подсмотреть все, что происходит. Но тут вопрос в том, какая задача перед вами стоит. Если вы не хотите показывать как реализована та или иная функция — это одно, но если вы хотите сделать так, чтобы скопированный код был бы не поддерживаем, имел встроенные «закладки» в виде, например, «демо-версия, купить тут» — то места для маневра становится больше.

Можно, например, разделить модуль на несколько файлов и чтобы основной модуль загружал оставшиеся части закодированные в битом base64, а с помощью невидимого кода «восстанавливать» код и дальше его распаковывать. (Пробовал такой вариант, но он очень сырой вышел). При этом сервер может каждый раз передавать разные варианты файла, что еще больше осложнит «сборку» вашего модуля на другом сервере. Да и в результате «кулхацкеры» все равно получат в руки кусок неподдерживаемого кода, который еще надо «завести» практически вслепую.
0 Magistr_AVSH28 ноября 2014 в 18:03#↵↑
Угу, примерно так я и собираюсь делать.
У меня задача — скрыть насколько это возможно реализацию протокола обмена с сервером (игра у меня сетевая), чтобы усложнить создание консольных клиентов. На код отрисовки графики или большую часть игровой логики (которой на клиенте почти нет) мне вообщем-то плевать, ничего особо ценного в нем нет.

Но да, самый лучший вариант — это и правда осложнить капитально сборку кода на другом сервере.

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

Буквально приходилось догадываться что где что — так что даже просто хорошая обфускация затрудняет взлом очень сильно. А если еще навесить скрытый код, еще прикрутить правила для сервера на отдачу скриптов только с определенного url и домена (если копипастишь — копипастить придется из браузера) и так далее, то разобрать это все конечно возможно, но становится явно сложно.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#6 dyvniy » Вт, 23 декабря 2014, 14:09:36

3D-симулятор кротовой норы и черной дыры из «Интерстеллар»
Naked Science
http://naked-science.ru/article/media/interstellar-app
https://github.com/sirxemic/Interstellar/tree/master/js
Изображение


Название раздела: Web на стороне клиента, Java Script
Описание: Наиболее перспективное направление развития компьютерных наук. Надо быть в теме!

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Web на стороне клиента, Java Script»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 1 гость