В
thisJavaScript есть больше, чем я показывал впрошлый раз . Время для более подробной информации о методах, замыканиях и глобальном объекте.
Это прямое продолжение этого в 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». Внутренняя функция действительно вызывается, но она не получит ссылку на oas 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 в этом посте являются спонсорскими.