Is possible to remove "freeze" status of a property in JavaScript? - javascript

If I freeze a property similar to something below, is it possible to undo the changes later without having to recreate the object?
var obj = Object.freeze({foo:'can you add more properties later?', bee: {ahh: '?'}});
Object.defineProperty(obj.bee,'ehh',{value: 'can you change me later?'});

No, when you freeze an object you're not able to change or add any property.
There is a function called Seal, that might be what you're looking for.
The Object.seal() method seals an object, preventing new properties
from being added to it and marking all existing properties as
non-configurable. Values of present properties can still be changed as
long as they are writable.

Related

Saving an object inside itself

How come I can store an object as it's own property? Here is a simple example:
let obj = {};
obj['obj'] = obj;
This will result in having an infinite object tree: I can call obj with obj.obj.obj.obj or even with obj.obj.obj.vobj.obj.obj.obj.obj.
Is this an issue for performance? It doesn't seem to bother the browser at all.
Actually, when I look at the console in Chrome and click to expand obj's properties it says (on the tooltip of i):
Value below was evaluated just now
So they were evaluated just when I clicked to expand.
Does this mean that JavaScript too will not look at obj's property until I actually access them?
Is obj.obj just a reference to obj?
Is this an issue for performance?
No. A circular reference is just as every other reference. Every class instance has actually a circular reference:
instance.constructor.prototype.constructor.protototype
Is obj.obj just a reference to obj?
Yes.
Does this mean that JavaScript too will not look at obj's property until I actually access them?
Yes. And the console won't try to expand it as it would get caught up in an endless loop.

manipulate/change the window.screen property values

Greetings dear community,
my goal is to spoof the screen object properties, but I can not just overwrite the properties by using:
window.screen[property] = number; or Object.defineProperty(...)
because these properties are read-only.
Therefore I wanted to kind of clone or recreate the screen object, manipulate the properties and then overwrite the whole window.screen object.
My attempt:
var clone = Object.create(Screen.prototype);
Object.assign(clone, window.screen);
console.log(clone);
The prototype is cloning well but not the properties.
After trying to get them with the Object.getOwnPropertyNames and Object.keys functions, which did not work either (example here), they have to be in the prototype.
So I tried this:
var clone = Object.create(Screen.prototype);
Object.assign(clone,Object.getPrototypeOf(window.screen));
console.log(clone);
which outputs the error "TypeError: 'get availWidth' called on an object that does not implement interface Screen."
Iterating with a for-in loop and assigning them does output the same error.
So it seems like I have to implement the interface Screen, even though I'm not sure if my plan is working after that. Perhaps there exists a simpler solution.
Other ideas:
I could assign the complete screen object as prototype (like that Object.create(screen)) and then set own properties on the object, but then the original values are still readable.
Maybe I also somehow can create an object by using Screen(...) interface?
Thanks for your help and ideas!
Seems like this is easily possible by the help of the Object.defineProperty() method, as long as the property is configurable.
var exampleProperty = 'colorDepth',
exampleValue = 55;
console.log("before:", screen[exampleProperty])
Object.defineProperty(screen, exampleProperty, {
// add descriptor properties here if desired
value: exampleValue
});
console.log("after:", screen[exampleProperty])

Difference between defining and assigning property

What is the difference between assigning a property to an object and defining it?Which one is better and how?
This
Object.defineProperty(obj,p,propDesc)
Or simply
obj.p="someValue";
Object.defineProperty lets you set a whole bunch of options about that property. Like enumerable and writable.
When you do obj.p = 'something';, you're setting a property with the "default" options.
Neither is "better", they each have their own uses. Which one you use depends on your requirements.
As found on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
"
This method allows precise addition to or modification of a property on an object. Normal property addition through assignment creates properties which show up during property enumeration (for...in loop or Object.keys method), whose values may be changed, and which may be deleted. This method allows these extra details to be changed from their defaults."

Function object in JavaScript

I think the Function object is the only instance in the JavaScript. All the other function(){...} or var xx=function(){...} are the objects inherited from this Function object. That is the prototype based language feature. And in prototype based language there is no Class, and One of the advantages of it is the object can changed anytimes.such as add a method or add a property into it. So, I think we can treat object like a key-values collection. You can add items into it anytimes after you created it. (If I was wrong, Please correct me.)
Say you have the code:
Function.test=function(){
alert(Function.name);//"Function"
alert(Function.myName);//"fun"
};
Function.name="fun";
Function.myName="fun";
Function.test();
In the above code, all I want to do is add a test method to the Function object.
There is no error found in this code. But why Function.name can not be changed?
First of all this property is not standard. This means that different browsers may treat it as they want. The second thing is that according to MDN it is read only.
A page from MDN states that the name of the Function cannot be changed because it's read only.

Does Object.defineProperty check if the property is defined?

I need to define property for a javascript object.
var obj = {};
obj['prop1'] = 1
In the above way, we can define the property.
Now, let us use Object.defineProperty
var obj = {};
Object.defineProperty(obj,'prop1',{value:1});
this is alternate way.
what is the difference between the two?
Does Object.defineProperty check if the property is already defined or not??
I believe obj['prop1'] = 1 checks for the property
thanks :)
EDIT
Any performance variation in between those?
Neither a direct object access, nor Object.defineProperty will "check" for existing properties. The only difference between those two is the possbility, to modify property descriptor values.
Property descriptors are
enumerable
configurable
writable
which are all set to true by using direct property access. With Object.defineProperty you have the option to set these properties individually. I suggest you read this MDN article to get an idea about the meanings.
If for instance, a propertie owns the flag configurable=false, you cannot overwrite or delete it (which might be the case for your issue).
Concerning performance:
Since Object.defineProperty is a function which needs to get executed each time, it has to be slower than a direct access on the object. I created this little benchmark:
http://jsperf.com/property-access-with-defineproperty
However, even if the difference looks drastically, you may not forget the value and reason for Object.defineProperty.
Mozilla says:
When the property already exists, Object.defineProperty() attempts to modify the property according to the values in the descriptor and the object's current configuration. If the old descriptor had its configurable attribute set to false (the property is said to be "non-configurable"), then no attribute besides writable can be changed. In that case, it is also not possible to switch back and forth between the data and accessor property types.
If a property is non-configurable, its writable attribute can only be changed to false.
A TypeError is thrown when attempts are made to change non-configurable property attributes (besides the writable attribute) unless the current and new values are the same.
in both cases, if property exists it's value will be overwritten, otherwise it will be created

Categories