Статьи

«это» в JavaScript против C #

Исходя из C # / C ++ / Java, использование thisключевого слова в JavaScript сбивает с толку. Это моя попытка объяснить это в терминах C # (C # очень близок к C ++ и Java). Я думал о написании этого поста долгое время, но только сейчас, когда я читаю JavaScript: Хорошие части  , я, наконец, понял это достаточно сам, чтобы иметь возможность объяснить это.

В C # (и C ++ и Java) thisключевое слово доступно внутри любого метода класса и относится к текущему объекту, используемому для вызова метода. Когда я впервые начал писать JavaScript, я предполагал, что это будет то же самое, но вскоре обнаружил, что я был неправ. thisв JavaScript есть другое поведение.

JavaScript объекты

Мое первое предположение было , что внутри методаthis ключевое слово будет ссылаться на текущий объект . Я был удивлен, когда все пошло не так, как я ожидал, но это не thisвина. Это было мое непонимание объектов и методов JavaScript. JavaScript является объектно-ориентированным, но это прототипная объектная ориентация, которая совсем не похожа на объектную ориентацию в C #.

Объекты JavaScript не похожи на объекты C #. Объект JavaScript представляет собой простое хранилище пар ключ-значение, которое намного больше похоже на словари C #. Мне стало намного легче понимать объекты JavaScript, когда я перестал думать о них как об объектах и ​​вместо этого думал о них как о словарях. На самом деле, в JavaScript, object.propertyэто просто сокращение дляobject["property"]

// Create an empty object.
var mySelf = {};
// Add a "name" property.
mySelf["name"] = "Anders";
document.write('mySelf["name"] = ' + mySelf["name"] + "<br/>");
document.write('mySelf.name = ' + mySelf.name + "<br/>");

Это результирующий вывод:

mySelf["Name"] = Anders
mySelf.Name = Anders

методы

Итак, если объект JavaScript является хранилищем значений ключей, таких как словари C #, как насчет методов? В C # словарь является хранилищем значений, в словарях нет такой вещи, как методы, если только они не хранят какой-то тип Actionили Func. Это то место, где различные базовые концепции снова нас обманывают. Прежде всего, в JavaScript функции являются объектами первого класса . Сейчас не время вдаваться в подробности о том, что это значит, поэтому давайте просто подумаем о них как о делегате C # статическому методу.

Внимательный читатель может подумать, что я просто сошел с ума. Я обещал объяснить thisв JavaScript , а затем я имею в виду статические методы — это полностью отсутствует доступ к this. Обещаю, я не сошел с ума. Я просто пытаюсь объяснить, что некоторые основные концепции JavaScript сильно отличаются от C #. Эти основные понятия затрагивают, казалось бы, простые вещи, такие какthis

Метод JavaScript — это просто свойство объекта, значение которого является функциональным объектом. Помните, что функции JavaScript являются объектами, а динамическая типизация JavaScript позволяет сохранять объекты любого типа в качестве свойства объекта. Давайте дополним mySelfобъект из предыдущего примера sayHelloметодом.

mySelf.sayHello = function() { document.write("Hello!") };

Звонок mySelf.sayHello()теперь добавляет «Привет!» к документу.

this и методы

Я надеюсь, что вы все еще со мной, потому что пришло время взглянуть на thisключевое слово. Из C # мы привыкли к методам, принадлежащим классу. Метод, к которому есть доступ, thisдолжен быть определен внутри класса. В JavaScript связь намного слабее. Функция сама по себе является объектом, который просто связан с объектом. Секрет JavaScript в thisтом, что он связан не с самой функцией, а с тем, как она вызывается . Одной и той же функции будут передаваться разные thisзначения в зависимости от того, как она вызывается. В простом случае, когда метод вызывается через свойство объекта, thisведет себя так, как ожидалось.

Давайте добавим getPaymentметод, который получает деньги для mySelf и обновляет или создает свойство cash mySelf, а также помощник showCash, который показывает текущую сумму денег.

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 + "
"); 
};
 
mySelf.getPayment = getPayment;
mySelf.showCash = showCash;
mySelf.getPayment(10);
mySelf.showCash();

Это создаст cashсвойство mySelfобъекта, как и ожидалось, поэтому mySelf.showCash();покажет ожидаемые текущие денежные средства.

Current Anders cash: 10

Это все на сегодня. В следующий раз   я расскажу подробнее о thisметодах, замыканиях и глобальном объекте.