Исходя из 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
методах, замыканиях и глобальном объекте.