Sterling Archer
Sterling Archer

Reputation: 22435

Object Read-Only Properties

I was reading this question about read-only properties, and I came upon this snippet:

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

Now, I know to hide the scope, you can use an IIFE, to also make a variable or property "private", but what I don't understand is:

Why is assignment allowed, and if it's allowed, how can nothing happen? In this snippet there is no inferred scope, so I don't understand how something in JS can infer a private property.

Upvotes: 5

Views: 2588

Answers (2)

Afonso Matos
Afonso Matos

Reputation: 2476

Getters and setters within object literal expressions are pure sugar over the Object.defineProperty() used in ES5.

What a getter does is that it returns a certain value, when a property of a certain object is requested.

let obj = {};
obj.foo = 3; // I am SETTING a property value
obj.foo; // I am GETTING the property value

So whenever you define a getter, every time you request a property, you get the value that that getter returns.

So if you have

let obj = {};

Object.defineProperty(obj, 'readOnly', {
    'get': function() { return 42; }
});

Or

let obj = {
    get readOnly() { return 42; }
};

Your variable will always be 42, because it can only return that value. You can try to set that property to any value, but in the end it will always return 42.

To forbidden assignment, you can add a setter and make it throw Error

Upvotes: 2

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276596

Why is assignment allowed, and if it's allowed, how can nothing happen? In this snippet there is no inferred scope, so I don't understand how something in JS can infer a private property.

Because assignments (before strict mode) never throw and making it throw would violate that invariant that people expect. While you can still override it (by making a setter and making that throw) this is the default behavior in JavaScript for properties. We don't like it but it is what it is.

If you use strict mode - you should get:

TypeError: setting a property that has only a getter

Upvotes: 6

Related Questions