Могут ли свойства только для чтения внедряться в Pure JavaScript?
Глядя на документацию mozilla, глядя на пример регулярного выражения (глава "Создание массива с использованием результата соответствия" ), мы имеют следующие утверждения:
input: свойство, доступное только для чтения, которое отражает исходную строку, с которой было сопоставлено регулярное выражение.
index: свойство только для чтения, которое является индексом совпадения в строке на основе нуля.
и т.д.... можно ли создать свой собственный объект в JavaScript, который будет иметь свойства только для чтения, или это привилегия, зарезервированная для встроенных типов, реализуемых конкретными браузерами?
Ответы
Ответ 1
Изменить:. Поскольку этот ответ был написан, новый, лучший способ использования Object.defineProperty
был стандартизирован в EcmaScript 5 с поддержкой в новых браузерах. См. Ответ Айдамина. Если вам нужно поддерживать "старые" браузеры, вы можете использовать один из методов в этом ответе как резерв.
В Firefox, Opera 9.5+ и Safari 3+, Chrome и IE (протестировано с v11) вы можете определить свойства getter и setter. Если вы только определяете геттер, он эффективно создает свойство только для чтения. Вы можете определить их в объектном литерале или путем вызова метода для объекта.
var myObject = {
get readOnlyProperty() { return 42; }
};
alert(myObject.readOnlyProperty); // 42
myObject.readOnlyProperty = 5; // Assignment is allowed, but doesn't do anything
alert(myObject.readOnlyProperty); // 42
Если у вас уже есть объект, вы можете вызвать __defineGetter__
и __defineSetter__
:
var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 42; });
Конечно, это не очень полезно в Интернете, потому что оно не работает в Internet Explorer.
Подробнее об этом можно узнать из John Resig blog или Центр разработчиков Mozilla.
Ответ 2
С любой интерпретатор javascript, который реализует ECMAScript 5, вы можете использовать Object.defineProperty для определения свойств readonly. В свободном режиме интерпретатор будет игнорировать запись в свойстве, в строгом режиме он выдает исключение.
Пример из ejohn.org:
var obj = {};
Object.defineProperty( obj, "<yourPropertyNameHere>", {
value: "<yourPropertyValueHere>",
writable: false,
enumerable: true,
configurable: true
});
Ответ 3
В JavaScript можно использовать свойства только для чтения, доступные с помощью методов getter. Обычно это называется шаблоном "Module".
В блоге YUI есть хорошая запись: http://yuiblog.com/blog/2007/06/12/module-pattern/
Отрывок из сообщения:
YAHOO.myProject.myModule = function () {
//"private" variables:
var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";
//"private" method:
var myPrivateMethod = function () {
YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
}
return {
myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."
myPublicMethod: function () {
YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
//Within myProject, I can access "private" vars and methods:
YAHOO.log(myPrivateVar);
YAHOO.log(myPrivateMethod());
//The native scope of myPublicMethod is myProject; we can
//access public members using "this":
YAHOO.log(this.myPublicProperty);
}
};
}(); // the parens here cause the anonymous function to execute and return
Ответ 4
Как свойство readint или переменная здесь.
Как helpamina сказал, и вот короткий код для тестирования, кстати, очень полезен теперь, когда JQuery притворяется, осуждает свойство selector.
<script>
Object.defineProperties(window, {
"selector": { value: 'window', writable: false }
});
alert (window.selector); // outputs window
selector ='ddd'; // testing because it belong to the global object
alert (window.selector); // outputs window
alert (selector); // outputs window
window.selector='abc';
alert (window.selector); // outputs window
alert (selector); // outputs window
</script>
Итак, у вас есть свойство readonly или переменная.
Ответ 5
Да, мы можем иметь свойство только для чтения для объекта в JavaScript. Это может быть достигнуто с помощью частной переменной и метода object.defineProperty()
,
См. следующий пример, иллюстрирующий объект, имеющий свойство только для чтения,
function Employee(name,age){
var _name = name;
var _age = age;
Object.defineProperty(this,'name',{
get:function(){
return _name;
}
})
}
var emp = new Employee('safeer',25);
console.log(emp.name); //return 'safeer'
emp.name='abc';
console.log(emp.name); //again return 'safeer', since name is read-only property
Ответ 6
Здесь ссылка на страницу Дугласа Крокфорда "Частные члены в Javascript".... мне кажется, что они будут прочитаны только в том случае, если будут предоставлены только методы getter и нет сеттеров:
http://javascript.crockford.com/private.html
Ответ 7
bob.js framework предоставляет способ объявить свойства только для чтения. Под капотом он объявляет частное поле и предоставляет функции геттера/сеттера для него. bob.js предоставляет несколько способов сделать то же самое, в зависимости от удобства и конкретных целей. Здесь один подход, который использует объектно-ориентированный экземпляр Property
(другие подходы позволяют определять сеттеры/геттеры для самого объекта):
var Person = function(name, age) {
this.name = new bob.prop.Property(name, true);
var setName = this.name.get_setter();
this.age = new bob.prop.Property(age, true);
var setAge = this.age.get_setter();
this.parent = new bob.prop.Property(null, false, true);
};
var p = new Person('Bob', 20);
p.parent.set_value(new Person('Martin', 50));
console.log('name: ' + p.name.get_value());
console.log('age: ' + p.age.get_value());
console.log('parent: ' + (p.parent.get_value ? p.parent.get_value().name.get_value() : 'N/A'));
// Output:
// name: Bob
// age: 20
// parent: N/A
В конце, p.name.set_value
не определяется, потому что это свойство только для чтения.
Ответ 8
Вы увидите, что я определил сеттер и getter для цвета, чтобы его можно было изменить. Бренд, с другой стороны, становится доступен только для чтения, как только объект определен. Я считаю, что это функциональность, которую вы искали.
function Car(brand, color) {
brand = brand || 'Porche'; // Private variable - Not accessible directly and cannot be frozen
color = color || 'Red'; // Private variable - Not accessible directly and cannot be frozen
this.color = function() { return color; }; // Getter for color
this.setColor = function(x) { color = x; }; // Setter for color
this.brand = function() { return brand; }; // Getter for brand
Object.freeze(this); // Makes your object public methods and properties read-only
}
function w(str) {
/*************************/
/*choose a logging method*/
/*************************/
console.log(str);
// document.write(str + "<br>");
}
var myCar = new Car;
var myCar2 = new Car('BMW','White');
var myCar3 = new Car('Mercedes', 'Black');
w(myCar.brand()); // returns Porche
w(myCar.color()); // returns Red
w(myCar2.brand()); // returns BMW
w(myCar2.color()); // returns White
w(myCar3.brand()); // returns Mercedes
w(myCar3.color()); // returns Black
// This works even when the Object is frozen
myCar.setColor('Green');
w(myCar.color()); // returns Green
// This will have no effect
myCar.color = 'Purple';
w(myCar.color()); // returns Green
w(myCar.color); // returns the method
// This following will not work as the object is frozen
myCar.color = function (x) {
alert(x);
};
myCar.setColor('Black');
w(
myCar.color(
'This will not work. Object is frozen! The method has not been updated'
)
); // returns Black since the method is unchanged
Вышеописанное было протестировано на Chromium Version 41.0.2272.76 Ubuntu 14.04 и получило следующий результат:
Porche
Red
BMW
White
Mercedes
Black
Green
Green
function () { return color; }
Black