Comments 31
Забавная идея. Вместо объекта в конструкторе можно использовать Object.create и тогда instanceof должен работать.
В ECMAScript 6 для приватных свойств можно использовать символы (уже доступно в Chrome, Firefox, io.js и node.js с версией от 0.12 включительно).
В ECMAScript 6 для приватных свойств можно использовать символы (уже доступно в Chrome, Firefox, io.js и node.js с версией от 0.12 включительно).
+3
Совсем приватные свойства с помощью символов не получится сделать, есть Object.getOwnPropertySymbols
-1
instance_of и прочие штуки не будут работать, видимо. Какой смысл делать полноценные приватные свойства? От кого их скрывать? Если пользователь либы хочет стрелять в ногу, пусть стреляет. Но иногда это помогает поправить поведение, если автор библиотеки не учел каких-то случаев / не хочет что-то менять.
+5
и отказывается от использования прототипов(создает методы для каждого экземпляра объекта заново)
Предложенный вами способ ведь точно так же создает методы для каждого экземпляра класса заново.
+1
вы про Animal.prototype.hello.bind(this)?
0
0
function(){
Animal.prototype.hello.apply(self, arguments)
}
0
Я, к сожалению, не могу понять, что вы имеете в виду этим кодом. Вы избавились от
bind(...)
? Тем не менее вы создаете новую анонимную функцию для каждого инстанса.+1
Да, но сама тяжеловесная функция остается в прототипе, не?
-1
С этим, конечно, не поспоришь.
Этот способ мне напоминает реализацию приватных свойств с помощью
Этот способ мне напоминает реализацию приватных свойств с помощью
WeakMaps
(пример). Только там нет возможной путаницы с this
и self
.0
Что вы имеете ввиду? Что современные js-движки настолько глупы, что для каждого объекта будут по новой компилить одну и туже тяжеловесную функцию?
+1
А как же способ спрятать приватные переменные в замыкании?
0
В вашем способе число создаваемых объектов будет вдвое больше, что скажется на объёме потребляемой памяти.
И вообще, зачем прятать приватные поля и методы? Они придуманы просто ради удобства и понимания кода. Просто используйте какую-нибудь нотацию приватных полей и всё.
И вообще, зачем прятать приватные поля и методы? Они придуманы просто ради удобства и понимания кода. Просто используйте какую-нибудь нотацию приватных полей и всё.
+3
Я просто оставлю это здесь github.com/azproduction/privatize ;]
0
Интересно, долго еще из Javascript с его системой наследования на базе прототипов будут пытаться сделать True OOP язык? ;)
+4
Это обычно пытаются сделать те, кто пришел в JS после многолетнего опыта с «True-ООП»-языками и уже мыслит в этой «True-ООП»-парадигме. С таким мышлением им приходится пытаться эмулировать поведение привычных им языков, хотя необходимости в этом нет.
+1
Согласен с вами, однако уже и классы в ES6 добавили.
+1
Нет. Те, кто приходят с True-ООП языков первым делом приходят в дикий восторг: «надо же, я могу в рантайме менять структуру всех объектов, офигеть!»
После чего эти люди начинают на каждое упоминание классов писать «не надо классов! вы не понимаете всей красоты прототипов!».
Через какое-то время до некоторых начинает доходить: «ну могу я структуру прототипа в рантайме поменять, ну что дальше?»
После чего эти люди начинают на каждое упоминание классов писать «не надо классов! вы не понимаете всей красоты прототипов!».
Через какое-то время до некоторых начинает доходить: «ну могу я структуру прототипа в рантайме поменять, ну что дальше?»
-1
Не знаю кто вас минуснул, странно.
А так:
Восторг это дело случая. Кто слезает с PHP не особо удивляется, ведь аналог там есть.
Про классы тоже дело случая, даже скорее вкусовщина. Кто-то хочет классов (я), а кто-то любит писать просто и без заморочек, структур и только базовый инструментарий.
А дальше смотря как принято в личном кодстайле и как в компании. Кто-то может добавить метод к классу (или изменить реализацию или бог его знает что ещё, возможностей и потребностей много), а кто-то связан по рукам и ногам правилом «не меняйте прототипы базовых классов».
Так же в зависимости от условий может быть по-разному реализован метод. И бывает так, что у тебя два варианта: встроить логику в метод или на основе логики создать тот или иной метод (например шаблонизатор может быть один и другой. Вы знаете на момент объявления метода какой есть шаблонизатор. Вы можете в теле проверять при каждом вызове или один раз создать метод с правильным вызовом)
А так:
Восторг это дело случая. Кто слезает с PHP не особо удивляется, ведь аналог там есть.
Про классы тоже дело случая, даже скорее вкусовщина. Кто-то хочет классов (я), а кто-то любит писать просто и без заморочек, структур и только базовый инструментарий.
А дальше смотря как принято в личном кодстайле и как в компании. Кто-то может добавить метод к классу (или изменить реализацию или бог его знает что ещё, возможностей и потребностей много), а кто-то связан по рукам и ногам правилом «не меняйте прототипы базовых классов».
Так же в зависимости от условий может быть по-разному реализован метод. И бывает так, что у тебя два варианта: встроить логику в метод или на основе логики создать тот или иной метод (например шаблонизатор может быть один и другой. Вы знаете на момент объявления метода какой есть шаблонизатор. Вы можете в теле проверять при каждом вызове или один раз создать метод с правильным вызовом)
0
Автор, вопрос в лоб: нужны мне, допустим, приватные и публичные свойства. И с теми и с другими должны уметь работать методы. Как быть?
0
Нужно разобраться, зачем нужны скрытые свойства.
1. Для защиты от страшных хакеров, которые «взломают» мой объект.
2. Для того, чтобы использующий класс программист, видел только его интерфейс и ему не мозолили глаза способы реализации.
Для 2-го вполне хватает jsdoc'ов с private и IDE'шек с автокомплитом.
1. Для защиты от страшных хакеров, которые «взломают» мой объект.
2. Для того, чтобы использующий класс программист, видел только его интерфейс и ему не мозолили глаза способы реализации.
Для 2-го вполне хватает jsdoc'ов с private и IDE'шек с автокомплитом.
+1
3. Для грамотного наследования без «леса» частных свойств и методов
4. Для того, чтобы после подключения библиотечного класса не лезли куда нельзя и не ломали что не надо.
Для 4-его есть культура программирования и установка не обращаться к метдам и свойствам, начинающихся с _ (подчёркивания)
Для 3 только если функцию создающую наследование допилить как-то. И пригодно только для JS, кофе лесом
4. Для того, чтобы после подключения библиотечного класса не лезли куда нельзя и не ломали что не надо.
Для 4-его есть культура программирования и установка не обращаться к метдам и свойствам, начинающихся с _ (подчёркивания)
Для 3 только если функцию создающую наследование допилить как-то. И пригодно только для JS, кофе лесом
Риторика
О необходимости вопрос равен вопросу применимости. Для маленьких проектов и скриптов по-настоящему пофиг. А для огромной монолитной системы с множественными наследованиями это уже актуально. Пишу на кофе, поэтому классы и наследование — стандартное явление.
+1
Если не наследоваться, а использовать как либу, то можно и кишками наружу. А при наследовании (если в либе все приватные свойства не сидят в замыкании конструктора) никакие подчёркивания не спасут. Если, например, я для обозначения приватности свойства использовал в его имени подчёркивание как и автор либы. Не лезть же в либу проверять нет ли совпадений для каждого _x (а при минифицировании тут вообще нет гарантий защиты от совпадения имён). Использовать в конструкторе либы var вместо this для приватного свойства нельзя, так как нужен доступ к свойству из метода, добавленного в prototype.
function Lib() {
this._private = 1;
}
Lib.prototype.getPrivate = function() {
return this._private;
}
function MyClass() {
this._private = 2;
}
MyClass.prototype = new Lib();
var myClass = new MyClass();
console.log("_private = " + myClass._private); // 2
console.log("getPrivate = " + myClass.getPrivate()); // 2
function Lib() {
var self = this; // свойство доступно только из конструктора
this._private = 1; // свойство доступно и из конструктора и из методов, добавленных через prototype
return {
getPrivate: function() {
return self.privateMethod();
},
// или
getPrivateAlt: Lib.prototype.privateMethod.bind(this)
}
}
Lib.prototype.privateMethod = function() {
return this._private;
}
function MyClass() {
this._private = 2;
}
MyClass.prototype = new Lib();
var myClass = new MyClass();
console.log("_private = " + myClass._private); // 2
console.log("getPrivate = " + myClass.getPrivate()); // 1
console.log("getPrivateAlt = " + myClass.getPrivateAlt()); // 1
+2
>>«Поскольку функция конструктор возвращает простой объект, не работает instanceof;»
Никто не мешает создаваемому объекту указать явно прототип Animal, вместо Object (создаем через Object.create, а не литерал). Тогда и instanceof будет работать корректно через цепочку прототипов и конструктор будет определяться верно у объекта.
Никто не мешает создаваемому объекту указать явно прототип Animal, вместо Object (создаем через Object.create, а не литерал). Тогда и instanceof будет работать корректно через цепочку прототипов и конструктор будет определяться верно у объекта.
0
Sign up to leave a comment.
Честные приватные свойства в прототипе