Are there other ways to bring privacy to our Objects?
Answer
As you may know from this lesson on privacy in objects, JavaScript does not have it built in, like other languages, ie. Java, C++.
The main way to convey a sense of privacy is to use underscored properties to signal other developers that the direct value of that property in the object is not to be touched, but what about when that is not enough; it could still be accessed. Another approach that developers use is closures; A closure is a function that is being called inside another function and has access to the state (data created or available ) of the calling function, yet nothing inside that function can be accessed from the outside, except its return. Here is an example, lets say we are using a factory function:
const Robot = (function() { //this is our factory function
function Robot(name) { // here we set up an inner function called robot that has a parameter name
this.getName = function() { // this refers to calling function and it is appending a getName
return name; // property with a functions that returns name
};
}
return Robot; // we return the function Robot
}()); // we call the function we assigned to the constant Robot
//now when I say:
const robbie = new Robot('Robbie'); //we create the new robot
console.log('the robot\'s name is: ' + robbie.getName()); // we see the name
delete robbie.name; // we try to delete the name
console.log('Robot\'s name: ' + robbie.getName() + ' stays private.'); // yet .name is inaccessible from the outside
Of course, there can be a catch, which is how much more it makes the computer work every time we were to create a new robot.
Also ES6 has the symbol function, which can help you mainly by increasing access complexity to the value by storing it in an object you donāt get to see and returning a symbol (unique character) that you can use to retrieve it, yet it is not truly private either, since you can access a list of them with the Object.getOwnPropertySymbols function.
Again, there are ways to secure your values, but there is no true privacy (as of yet, or that I know of) in JavaScript Objects,
Interesting! Hadnāt heard of Object.freeze(). If we add it to the exercise before reassigning _energyLevel:
const robot = {
_energyLevel: 100,
recharge(){
this._energyLevel += 30;
console.log(`Recharged! Energy is currently at ${this._energyLevel}%.`)
}
};
Object.freeze(robot);
robot._energyLevel = 'high'; // fails, but doesn't cause an error
robot.recharge(); // doesn't increase _energyLevel
Output: Recharged! Energy is currently at 100%.
According to the docs, it will work⦠for primitives only.
The result of calling Object.freeze(object) only applies to the immediate properties of object itself and will prevent future property addition, removal or value re-assignment operations only on object . If the value of those properties are objects themselves, those objects are not frozen and may be the target of property addition, removal or value re-assignment operations.
Hi! It said in the lesson that there is no āprivacy built-in for objectsā in JS. But in the documentation said that there are descriptors, that control the way we can use the properties in the object. And we can put keys ( āwritableā, āenumerableā, āconfigurableā) for each property of the object to set up it. Object.defineProperties()
And there are some methods to prevent changes on the whole object:
Object.preventExtensions(obj), Object.seal(obj), Object.freeze(obj).
So maybe this information wasnāt given to us because it is the course for bigginers?
I thought .this could only refer to objects. Here you say it refers to a function. How does that work?
Also, I could not follow the example because everything is just described as āfunctionā when there are multiple functions!
And another question, why does the factory function not have any parameters? Doesnāt the nested function have to access the name argument thatās passed to it??
const robot = new obj(āFooā);
when I do console.log(robot); I get the following:
obj { getName: [Function] }
so there really isnt any property called name on the object after running that code from above.
So executing delete robot.name; has no effect at all from my point of view.
And if I execute delete on the only property (getName) delete robot.getName; it is removed and when we execute console.log(robot.getName(); after it we will get an error stating that it does not exist.
Correct me if Iām wrong but is it possible that the example isnāt really working as expected because delete robot.name; has no effect at all?
In cases where JavaScript is used to enable web browser-based functionality in a website, privacy becomes pretty much void.
Remembering that modern browsers come with some form of developer console, one can easily inspect the HTML, CSS and JavaScript code of any given page thatās currently displayed.
A visitor to a website can also, with the developer console, alter the look and behaviour of a website page, at least temporarily until the page is refreshed: add the odd HTML, or CSS here and there, or locate and modify any of the visible JavaScript, and presto the page behaves differently.
So, in website coding at least, it is important to never place critical code in JavaScript, such as authentication mechanisms for example.