Чтобы создать класс JavaScript с открытым методом, я бы сделал что-то вроде:
function Restaurant() {}
Restaurant.prototype.buy_food = function(){
// something here
}
Restaurant.prototype.use_restroom = function(){
// something here
}
Таким образом, пользователи моего класса могут:
var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();
Как создать закрытый метод, который может вызываться методами buy_food
и, use_restroom
но не внешне пользователями класса?
Другими словами, я хочу, чтобы моя реализация метода могла делать:
Restaurant.prototype.use_restroom = function() {
this.private_stuff();
}
Но это не должно работать:
var r = new Restaurant();
r.private_stuff();
Как я могу определить private_stuff
как частный метод, чтобы оба они выполнялись ?
Я несколько раз читал рецензию Дуга Крокфорда, но не похоже, что «частные» методы могут вызываться публичными методами, а «привилегированные» методы могут вызываться извне.
javascript
oop
private-methods
Уэйн Као
источник
источник
Использование самовозвратной функции и вызова
JavaScript использует прототипы и не имеет классов (или методов в этом отношении), таких как объектно-ориентированные языки. Разработчик JavaScript должен думать на JavaScript.
Цитата из Википедии:
Решение с использованием самозапуска и функцию вызова для вызова частного «метода»:
call позволяет нам вызывать приватную функцию с соответствующим context (
this
).Проще с Node.js
Если вы используете node.js , вам не нужен IIFE потому что вы можете воспользоваться системой загрузки модулей :
Загрузите файл:
(экспериментальный) ES7 с оператором Bind
Оператор связывания
::
является предложением ECMAScript и реализован в Babel ( стадия 0 ).Загрузите файл:
источник
.call
части.f()
в javascript нет приватного (не на данный момент)..call
) и малую память (нет функций в экземпляре)? Это вообще существует?Вы можете смоделировать частные методы, как это:
Больше информации об этой технике здесь: http://webreflection.blogspot.com/2008/04/natural-javascript-private-methods.html
источник
В этих ситуациях, когда у вас есть общедоступный API и вам нужны частные и общедоступные методы / свойства, я всегда использую Шаблон модуля. Этот шаблон стал популярным в библиотеке YUI, а подробности можно найти здесь:
http://yuiblog.com/blog/2007/06/12/module-pattern/
Это действительно просто и легко для других разработчиков. Для простого примера:
источник
aPrivateMethod = function() { MYLIB.aPublicProperty}
?Вот класс , который я создал , чтобы понять , что Дуглас Крокфорд имеет предложил в своем месте Частные Члены в JavaScript
источник
that
используется вместо того,this
чтобы избежать проблем с областью видимости, когда функции связаны с другим объектом. Здесь вы хранитеthis
вthat
и никогда не использовать его снова , которая является такой же , как не делать этого вообще. Вы должны изменитьthis
соthat
всейConstructor
внутренней функции (не методы декларации). Еслиemployee
этоapply
ed илиcall
ed каким-то образом, эти методы могутthis
вызвать, так как будут неправильно связаны.Я придумал это: РЕДАКТИРОВАТЬ: На самом деле, кто-то связал с тем же решением. Duh!
источник
var getAwayVehicle = new Car(100);
где100
скорость, и вы хотите предупредить скорость. Спасибо!var Car = function(speed) { this.speed = speed; }
и `return {constructor: Car, ...`Я думаю, что такие вопросы возникают снова и снова из-за непонимания замыканий. Закрытие - самая важная вещь в JS. Каждый программист JS должен чувствовать суть этого.
1. Прежде всего нам нужно сделать отдельную область (закрытие).
2. В этой области мы можем делать все, что хотим. И никто не узнает об этом.
3. Чтобы мир узнал о нашем ресторанном классе, мы должны вернуть его из закрытия.
4. В итоге имеем:
5. Кроме того, этот подход имеет потенциал для наследования и шаблонирования
Я надеюсь, что это помогает кому-то лучше понять эту тему
источник
Лично я предпочитаю следующий шаблон для создания классов в JavaScript:
Как видите, он позволяет вам определять как свойства класса, так и свойства экземпляра, каждое из которых может быть открытым и закрытым.
демонстрация
Смотрите также эту скрипку .
источник
Все это закрытие обойдется вам. Убедитесь, что вы протестировали значения скорости, особенно в IE. Вы найдете, что вам лучше с соглашением об именах. Все еще есть много корпоративных веб-пользователей, которые вынуждены использовать IE6 ...
источник
Не будь таким многословным. Это Javascript. Используйте соглашение об именах .
После нескольких лет работы в классах es6 я недавно начал работать над проектом es5 (используя requireJS, который уже очень многословен). Я перебрал все стратегии, упомянутые здесь, и все сводится к использованию соглашения об именах :
private
. Другие разработчики, входящие в Javascript, будут знать об этом заранее. Поэтому простого соглашения об именах более чем достаточно. Простое соглашение по именованию префикса с подчеркиванием решает проблему как частных свойств, так и частных методов.мой-tooltip.js
источник
define
, иconstructor
сама структура. Хотя я в основном согласен с ответом, я начал работать с JS с большим влиянием ООП и даже слишком рано переключился на TS, так как у меня был опыт работы с C #. Я думаю, что я должен отучиться от всего этого и понять парадигму прототипирования / процедур. (одобрено, кстати)Вы можете сделать это сейчас с закрытыми методами es10 . Вам просто нужно добавить
#
перед именем метода.источник
Возьмите любое из решений, которые следуют частному или привилегированному образцу Крокфорда . Например:
В любом случае, когда злоумышленник не имеет права «выполнить» в контексте JS, у него нет возможности получить доступ к каким-либо «открытым» или «закрытым» полям или методам. Если у злоумышленника есть такой доступ, он может выполнить следующую однострочную строку:
Обратите внимание, что приведенный выше код является общим для всех конструкторов-типов-конфиденциальности. Он потерпит неудачу с некоторыми решениями здесь, но должно быть ясно, что почти все решения, основанные на замыканиях, могут быть разбиты таким образом с другими
replace()
параметрами.После этого любой объект, созданный с помощью
new Foo()
, будет иметьeval
метод, который можно вызывать для возврата или изменения значений или методов, определенных в замыкании конструктора, например:Единственная проблема, с которой я могу столкнуться, заключается в том, что она не будет работать в тех случаях, когда существует только один экземпляр, и он создается при загрузке. Но тогда нет никакой причины фактически определять прототип, и в этом случае злоумышленник может просто воссоздать объект вместо конструктора, если у него есть способ передать те же самые параметры (например, они являются постоянными или вычисляются из доступных значений).
На мой взгляд, это в значительной степени делает решение Крокфорда бесполезным.Поскольку «конфиденциальность» легко нарушается, недостатки его решения (сниженная читаемость и удобство обслуживания, сниженная производительность, увеличенная память) делают метод, основанный на прототипах «без конфиденциальности», лучшим выбором.
Я обычно использую начальные подчеркивания для обозначения,
__private
а также для_protected
методов и полей (стиль Perl), но идея сохранения конфиденциальности в JavaScript просто показывает, как это неправильно понимается.Поэтому я не согласен с Крокфордом за исключением его первого предложения.
Так как же получить настоящую конфиденциальность в JS? Поместите все, что требуется для приватности на стороне сервера, и используйте JS для выполнения вызовов AJAX.
источник
(function () {allMyStuff}());
чтобы не показывать ничего глобального.f.eval('nameOfVariable')
когда ты не знаешь, что'nameOfVariable'
...Апофеоз шаблона модуля: выявление шаблона модуля
Маленькое аккуратное продолжение очень прочного рисунка.
источник
Если вам нужен полный спектр открытых и закрытых функций с возможностью доступа к закрытым функциям для открытых функций, создайте код для такого объекта:
источник
new MyObject
, прототипMyObject
заменяется одинаковыми значениями..prototype
внутрь конструктора.Похож на georgebrock, но немного менее многословно (ИМХО) Есть какие-то проблемы с этим? (Я нигде не видел)
редактировать: я понял, что это несколько бесполезно, поскольку каждая независимая реализация имеет свою собственную копию открытых методов, что подрывает использование прототипа.
источник
Вот что мне больше всего понравилось в отношении приватных / публичных методов / членов и создания экземпляров в javascript:
вот статья: http://www.sefol.com/?p=1090
и вот пример:
JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/
источник
Шаблон модуля является правильным в большинстве случаев. Но если у вас есть тысячи экземпляров, классы сохраняют память. Если сохранение памяти является проблемой, и ваши объекты содержат небольшое количество личных данных, но имеют много открытых функций, то вы захотите, чтобы все открытые функции жили в .prototype для экономии памяти.
Вот что я придумал:
Объект
priv
содержит частные свойства. Он доступен через публичную функциюgetPriv()
, но эта функция возвращается,false
если вы не передадите ейsecret
, и это известно только внутри основного замыкания.источник
Что насчет этого?
Поиск закрытой переменной невозможен за пределами непосредственной функции. Нет дублирования функций, экономия памяти.
Недостатком является то, что поиск частных переменных является неуклюжим
privateVars[this.id].cooked
для ввода. Также есть дополнительная переменная id.источник
Restaurant
как ,undefined
потому что вы ничего не возвращаются из анонимной функции.Restaurant
был собран мусором, его значения остаются внутриprivateVars
. АWeakMap
может быть хорошей заменойArray
в этом случае.Обернуть весь код в анонимную функцию: тогда все функции будут частными, ТОЛЬКО функции, прикрепленные к
window
объекту:Использовать этот :
FIDDLE
источник
Я предпочитаю хранить личные данные в связанном
WeakMap
. Это позволяет вам хранить ваши открытые методы на прототипе, к которому они относятся. Это, кажется, самый эффективный способ справиться с этой проблемой для большого количества объектов.источник
Частные функции не могут получить доступ к общедоступным переменным, используя шаблон модуля
источник
Поскольку каждый выкладывал здесь свой код, я тоже это сделаю ...
Мне нравится Крокфорд, потому что он ввел реальные объектно-ориентированные шаблоны в Javascript. Но он также придумал новое недоразумение, «это».
Так почему он использует «это = это»? Это не имеет никакого отношения к частным функциям вообще. Это связано с внутренними функциями!
Потому что, согласно Крокфорду, это ошибочный код:
Поэтому он предложил сделать это:
Поэтому, как я уже сказал, я совершенно уверен, что Крокфорд ошибся в его объяснении об этом и об этом (но его код, безусловно, правильный). Или он просто дурачил мир Javascript, чтобы знать, кто копирует его код? Я не знаю ... Я не фанат браузера; D
РЕДАКТИРОВАТЬ
Ах, вот в чем суть: что означает «var this = this»; значит в JavaScript?
Так что Кроки действительно был не прав с его объяснением ... но с его кодом, так что он все еще отличный парень. :))
источник
В общем, я временно добавил приватный объект _. Вы должны открыть конфиденциальность в «Power-constructor» для метода. Если вы вызовете метод из прототипа, вы сможете перезаписать метод prototype
Сделайте публичный метод доступным в «Power-constructor»: (ctx - контекст объекта)
Теперь у меня есть эта openPrivacy:
источник
Это то, что я разработал:
Требуется один класс кода сахара, который вы можете найти здесь . Также поддерживает защищенные, наследования, виртуальные, статические вещи ...
источник
https://github.com/nooning/JSClass
источник
Я создал новый инструмент, который позволит вам иметь настоящие частные методы на прототипе https://github.com/TremayneChrist/ProtectJS
Пример:
источник
_private
метод?Вы должны поместить замыкание вокруг вашей фактической функции-конструктора, где вы можете определить свои частные методы. Чтобы изменить данные экземпляров с помощью этих закрытых методов, вы должны передать им «this» вместе с ними, либо в качестве аргумента функции, либо путем вызова этой функции с помощью .apply (this):
источник
new Restaurant
будет свой собственныйrestaurant
конструктор, и «прототип» будет полностью нарушен.Я знаю, что уже слишком поздно, но как насчет этого?
источник
На этот вопрос уже есть много ответов, но ничто не соответствовало моим потребностям. Поэтому я придумала собственное решение, надеюсь, оно кому-нибудь пригодится:
Как вы можете видеть, эта система работает при использовании этого типа классов в JavaScript. Насколько я понял, ни один из методов, упомянутых выше, не сделал.
источник
Посмотрите этот ответ для чистого и простого «классного» решения с приватным и общедоступным интерфейсом и поддержкой композиции.
источник