查看mozilla文档,在正则表达式示例中(标题为“使用匹配结果创建数组”),我们有以下语句:
input: 只读属性,反映了正则表达式匹配的原始字符串。
index: 只读属性,是匹配项在字符串中零索引位置。
等等……在JavaScript中是否可以创建自己的对象,并具有只读属性,或者这是由特定浏览器实现的内置类型所保留的特权?
查看mozilla文档,在正则表达式示例中(标题为“使用匹配结果创建数组”),我们有以下语句:
input: 只读属性,反映了正则表达式匹配的原始字符串。
index: 只读属性,是匹配项在字符串中零索引位置。
等等……在JavaScript中是否可以创建自己的对象,并具有只读属性,或者这是由特定浏览器实现的内置类型所保留的特权?
var obj = {};
Object.defineProperty( obj, "<yourPropertyNameHere>", {
value: "<yourPropertyValueHere>",
writable: false,
enumerable: true,
configurable: true
});
编辑:自从写下这个答案以来,使用Object.defineProperty
的一种新而更好的方法已经在EcmaScript 5中标准化,并得到了较新浏览器的支持。请参见Aidamina的答案。如果您需要支持“旧”浏览器,可以使用本答案中的某种方法作为后备。
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; });
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
以下是只读属性或变量。
正如aidamina所说,这里有一个简短的测试代码,顺便说一下,现在非常有用,因为JQuery假装弃用了选择器属性。
<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>
是的,我们可以在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
_name
变成了#name
,它是真正的私有的。请参见下面的答案。 - jordanfb 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's 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
Porche
Red
BMW
White
Mercedes
Black
Green
Green
function () { return color; }
Black
Object.freeze()
。ECMAScript 5添加了Object.seal
和Object.freeze
方法。seal方法将防止属性添加,但允许编写/编辑属性。Object.freeze
方法将完全锁定一个对象,它们将保持冻结时的状态。 - S.SerpooshanObject.defineProperty(Fake.prototype, 'props', {
set: function() {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
},
});
引用自 React
其他答案是正确的,但没有人提到私有类字段,这是定义只读属性的另一个选项(假设类在您的用例中有意义):
class Car {
color = ''; // public field
#serialNumber = ''; // # is a private field
constructor(color, serialNumber) {
this.color = color;
this.#serialNumber = serialNumber;
}
// Public read-only access to serial number
get serialNumber() {
return this.#serialNumber;
}
}
const car = new Car('black', '123XYZ');
car.color = 'red'; // Changes color
car.serialNumber; // Returns private value
car.serialNumber = 'other'; // Does nothing
car.serialNumber; // Returns private value as before
bob.js 框架 提供了一种声明只读属性的方法。在内部,它声明了一个私有字段,并公开了用于获取/设置该字段的函数。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
未定义,因为那是一个只读属性。
Object.seal
可以防止向对象添加新属性(但现有属性可以更改),而Object.freeze
则可以防止对对象进行任何更改。Object.seal
和Object.freeze
都得到了很好的支持。 - Dave F