Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 18.02.2016, 15:28
Новичок на форуме
Отправить личное сообщение для kaban4ig Посмотреть профиль Найти все сообщения от kaban4ig
 
Регистрация: 18.02.2016
Сообщений: 1

Обработка двойных ()
var global = (function () {
				return this || (1, eval)('this');
			}());

Подскажите как обрабатывается код такого вида.

(1, eval)('this')
Ответить с цитированием
  #2 (permalink)  
Старый 19.02.2016, 00:05
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сначала посмотрим на такой пример:
var x = 0;

(function () {
    var x = 1;

    eval('alert(x)'); // 1
    (1, eval)('alert(x)'); // 0

}());
∙ Для кода, выполненного через просто eval(…), доступен скоп текущей функции, поэтому берется значение локальной переменной x.
∙ Для кода, выполненного через (1, eval)(…), доступен только глобальный скоп, поэтому берется значение глобальной переменной x.

Чтобы понять, почему так происходит, рассмотрим обычный метод объекта:
var obj = {
    method: function () {
        return this;
    }
};

var method = obj.method;

alert(obj.method() === obj) // true
alert(method() === window) // true
Как видим, когда вызываем метод через аксессор obj.method, то объектом активации функции становится сам obj и this является ссылкой на него.
А когда мы вызываем метод по прямой ссылке, то его объектом активации становится глобальный контекст, в случае браузерного JS – это window, и this в этом случае является ссылкой на window.

Вернемся к eval:
(1, eval)
Это обычное выражение, результатом которого является ссылка на функцию eval. Возвращается последнее значение после запятой. Но как можно заметить в обычном вызове eval(…) тоже нет объекта активации. Это особенность функции eval, объектом активации для нее является текущий скоп. Как оно там внутри реализовано мы не знаем, но можем представить происходящее следующим псевдокодом:
var x = 0;

function eval(code) {
    with (this) {
        return (function () {

            return // результат выполнения code

        }).call(this.context);
    }
}

globalScope → {
    x: 0,
    eval: eval,
    context: window
}

(function () {
    var x = 1;

    localScope → {
        x: 1,
        eval: eval,
        context: window
    }

    localScope.eval('alert(x)'); // 1
    
    globalScope.eval('alert(x)'); // 0

}());
Трюк (1, eval) отвязывает функцию eval от локального скопа. Не обязательно писать (1, eval), можно как во втором примере получить ссылку на функцию:
var x = 0;

(function () {
    var x = 1;

    eval('alert(x)'); // 1

    var globalEval = eval;
    globalEval('alert(x)'); // 0

}());
Эффект будет такой же.

Соответственно в твоем примере (1, eval)('this') используется для получения глобального контекста.
Такую запись можно заменить на new Function('return this')().

Последний раз редактировалось Octane, 19.02.2016 в 09:01.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка ajax ошибок Tek Angular.js 5 15.05.2014 14:10
Обработка нажатия на элемент и его родитель klev2004 Общие вопросы Javascript 3 12.12.2012 20:07
обработка элементов форм stalker77 Элементы интерфейса 3 26.06.2012 13:44
jqGrid. локальная обработка данных DarkN jQuery 0 25.01.2011 23:55
Обработка фото сервером. mycoding Оффтопик 0 12.10.2010 22:45