Тэги

Silverlight (36) WPF (10) IIS (7) Visual Studio (7) SharePoint (6) .Net Framework (5) ODP.NET (5) ASP.NET (4) C# (4) common (4) Network Settings (3) JavaScript (2) MS Office (2) Resharper (2) WCF (2) WEB (2) XPath (2) XSLT (2) ADO.NET (1) APEX (1) CMD (1) CSS (1) EF (1) HTML (1) Hardware bugs (1) Java (1) MS SQL (1) Oracle (1) PDF (1) Version Control (1) XAML (1)

пятница, 26 августа 2011 г.

Коллизия нотации "(function)();" в JavaScript или почему JavaScript разработчик будет ставить точку с запятой перед (function)();

Нотацию (function)(); в JavaScript всегда надо начинать с точки с запятой.
Это защитит от трудно определимой ошибки в интерпретации кода JavaScript-движком.


Нотация (function)(); в JavaScript чаще всего применяется в следующих случаях:
  • когда вы хотите ограничить видимость локальных переменный и поиграть с замыканиями (closures), при этом вызывая немедленное выполнение.
  • когда в проекте используется несколько JavaScript фреймворков и они бодаются за переменную по имени $. Эта нотация помогает гарантированно использовать переменную $, независимо от будущих изменений на сайте.
Пример:

;(function ($) { /* do something*/ })(jQuery);


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

function f1(inp) { alert("f1 - " + inp); }

// Ошибки не будет, все в порядке.
var f2 = function (inp) { alert("f2 - " + inp); }
; (f1)("2");

// Если следующую строку не завершить точкой с запятой, будет ошибка.
var f3 = function (inp) { alert("f3 - " + inp); }
(f1)("2");

// Если следующую строку также не завершить точкой с запятой, будет ошибка.
var int1 = 1
(f1)("1");

Причины применения:
  • Частый рефакторинг и масштабирование кода.
  • Объявления метода в переменную (var f2 = function(){}) стандартная практика, при этом закрывающая метод фигурная скобка и тело метода скрывает наглядность того, что это объявление переменной.

Отличие создания свойств объекта в конструкторе и через прототип конструктора в JavaScript.

Свойства, задаваемые в конструкторе, нельзя подменять через прототип.
Т.е. свойство задаваемое в конструкторе скрывает одноименное свойство в прототипе.

Например, для конструктора
function c() { this.a = "a"; }
запись
c.prototype.a = "a2";
не имеет смысла
(если не обращаться из объекта реализации напрямую, например myObj.constructor.prototype.a).


Далее JavaScript код для просмотра в дебаггинге.
Здесь метод assert никогда не будет выполнен.


var assert = function (res) { if (res !== true) alert("false"); }

function c() { this.a = "a"; }

c.prototype.b = "b";
var t1 = new c();
c.prototype.a = "a2";
c.prototype.b = "b2"; var t2 = new c();

assert(t1.a == t2.a);
assert(t1.a == "a");
assert(t1.b == t2.b);
assert(t1.b == "b2");