В
this
JavaScript есть больше, чем я показывал впрошлый раз . Время для более подробной информации о методах, замыканиях и глобальном объекте.
Это прямое продолжение этого в JavaScript против C # поста. Если вы еще не прочитали это, я предлагаю вам прочитать это, прежде чем продолжить здесь.
Подробнее о методах
В прошлый раз я закончил с примером кода с методом, который позволил мне получать платежи и показывать мой текущий уровень наличности. В этом посте я добавлю ту же функцию, что и метод, к другому объекту.
// Repeated from old post var mySelf = {}; mySelf["name"] = "Anders"; var getPayment = function (amount) { // Initialize to 0 if no cash property. this.cash = (this.cash || 0) + amount; }; var showCash = function() { document.write("Current " + this.name + " cash: " + this.cash + "<br/>"); }; mySelf.getPayment = getPayment; mySelf.showCash = showCash; mySelf.getPayment(10); mySelf.showCash(); // New content computerShop = { getPayment: getPayment, showCash: showCash, name: "Computers inc." }; computerShop.getPayment(100); computerShop.showCash();
computerShop
Повторно используют getPayment
и showCash
функцию в качестве методов. Теперь одна и та же функция используется в качестве метода двух разных объектов. Функция получит текущий объект как this
, благодаря тому, this
что связана с вызовом метода, а не привязана к объекту.
Глобальный объект
Что если функция вызывается напрямую — у нас есть ссылка на нее в getPayment
переменной?
getPayment(42); showCash();
Вывод в документ показывает, что значение действительно сохраняется между вызовами функции:
Current cash: 42
Чтобы иметь возможность сохранить значение, функции используют this
. Даже если функции не были вызваны как метод, this
был действительным.
В JavaScript всегда есть this
. Если ничего не указано, this
это глобальный объект (так же, как и где хранятся глобальные переменные).
cash = 17; showCash();
Это теперь покажет денежную стоимость как 17 вместо. Использование глобального объекта, конечно, не рекомендуется. Глобальные переменные — это запах кода на любом языке, поскольку это неизбежно при столкновении имен в больших программах. Способ определения модулей в JavaScript — использовать замыкания. Я не буду сейчас вдаваться в подробности о замыканиях для создания модулей, но покажу важное отличие в обработке замыканий между C # и JavaScript.
Затворы
Закрытие — это возможность для внутренней функции получить доступ к переменным внешней функции (даже если внешняя функция уже вернулась). Пока что C # и JavaScript равны. Когда дело доходит до this
обработки, они ведут себя по-разному, что важно знать, чтобы избежать неприятных сюрпризов.
В C # внутренняя функция имеет доступ к this
внешней функции.
class C { int i = 0; public void F() { Action a = () => this.i = 42; a(); Console.WriteLine(i); } }
Вызов F()
распечатает 42. Соответствующий код JavaScript действителен. Но это не будет делать то же самое.
var o = { i : 0, F : function() { var a = function() { this.i = 42; }; a(); document.write(this.i); } }; o.F();
Вывод в документ будет «0». Внутренняя функция действительно вызывается, но она не получит ссылку на o
as this
. Помните, что именно то, как вызывается функция , определяет значение this
. Если он не вызывается с синтаксисом метода, this
будет глобальный объект. Мы только что создали новую глобальную переменную i
со значением 42.
Проходя вручную this
Есть способ обработать последний пример: используя JavaScript apply
или call
функции (разница в том, как передаются аргументы, в этом примере нет аргументов, поэтому оба работают одинаково). Ближайший родственник в C # — это методы расширения, где this
параметр передается явно.
var p = { i : 0, F : function() { var a = function() { this.i = 42; }; a.apply(this); document.write(this.i); } }; p.F();
Последний пример выведет 42.
Захват this
вthat
В предыдущем примере this
был передан напрямую с помощью apply
метода. Во многих случаях такой подход невозможен, т. Е. При передаче функции для последующего использования в качестве обратного вызова некоторой библиотекой. В этом случае соглашение заключается в захвате this
переменной that
для использования во внутренней функции.
var q = { i: 0, F: function F() { var that = this; var a = function () { that.i = 42; } a(); document.write(this.i); } } q.F();
JavaScript не является C #
JavaScript определенно является мощным языком, но он совсем не похож на C #, как предполагает синтаксис. Я продолжу читать JavaScript: хорошие части, чтобы узнать больше об этом. Скорее всего, будет больше сообщений в блоге.
Ссылки на Amazon в этом посте являются спонсорскими.