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
Related
What does this JavaScript error actually mean? I'm not asking about my specific case, just generally how is this error message meant to be understood?
TypeError: 'get' on proxy: property 'items' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '[object Array]' but got '[object Array]')
I don't understand why JavaScript would care what the proxy returns? Why does it matter if its "its actual value" or something else? Isn't what what proxies are (sometimes) used for - returning data in place of the original result?
Additionally - in my specific version of this error message, it appears that the expected type is the same as the returned type so that confuses me even more.
Apparently the restriction that causes this error comes from the ECMAScript spec for Proxies, see this section.
[[Get]] for proxy objects enforces the following invariants:
The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable own data property.
The value reported for a property must be undefined if the corresponding target object property is a non-configurable own accessor property that has undefined as its [[Get]] attribute.
So if a property of an object is non-writable and non-configurable, the proxy that wraps this object must return the exact same value that the property of the source object holds when the property is read.
In my case the issue was caused by Vue reactifying a non-writable and non-configurable object property and returning the property's value wrapped in another proxy, which broke that rule.
The rule kind of makes sense if you see the proxy as "the same" as the source object. If that source object's property is read-only and not configurable, then any proxy for that object should also not be able to change the value of that property. I'm not sure if I agree, however, because at the end of the day the proxy is not the source object and so I think it should be up to it to decide whether or not to follow the rules of the source object, but maybe I'm missing something.
I am reading about getters and setters in javascript. I would like to know if there is a difference between this two ways of coding with and without setters
first way, without setters.
>obj1 = {
arr: [];
}
>obj1.arr.push('first')
>obj1.arr
[ 'first' ]
Second way, with setters.
>obj2 = {
set add(data) {
this.arr.push(data);
},
arr: []
}
>obj2.add = 'first'
>obj2.arr
[ 'first' ]
The setter syntax in your example does not really prevent the client code to still add a value using the direct push call as in the first code block. So the difference is that you just added another way to do the same thing.
To make a fair comparison, you would have to define the same method in both alternatives: once as a normal method and once as a setter method, and then the difference is just the syntax how the argument is passed to the method, either with obj.add('first') or obj.add = 'first'.
In this actual case I would vote against the setter, because it gives the false impression that if you "assign" another value, the first assigned value is overwritten:
obj.add = 'first';
obj.add = 'second';
... but obviously this is not the case: both values exist in the object now.
First, The set Syntax bind an object property to a defined function. In this particular example, there is no difference between two codes, but let's say for example you want to check if the value is negative before adding it to the array, so you can use set to Encapsulate that behavior.
So basically, using setter is only to add additional encapsulated behavior to the functions of the objects.
The way of accessing the array index called bracket notation. it is equal to dot notation, except the bracket notation allows you to set new properties to objects or arrays dynamically.
Hope this help you.
I think difference only about "how it looks like". Using setters it's closest way for understanding for people who came to js from object oriented languages.
The getter/setter property is not the same as "normal" instance property, one is called "named data property", the other is called "named accessor property".
Please let met quote below part of documents from the ECMAScript 5.1.
https://www.ecma-international.org/ecma-262/5.1/#sec-8.10.1
An Object is a collection of properties. Each property is either a
named data property, a named accessor property, or an internal
property:
A named data property associates a name with an ECMAScript language
value and a set of Boolean attributes.
A named accessor property associates a name with one or two accessor
functions, and a set of Boolean attributes. The accessor functions are
used to store or retrieve an ECMAScript language value that is
associated with the property.
An internal property has no name and is not directly accessible via
ECMAScript language operators. Internal properties exist purely for
specification purposes.
There are two kinds of access for named (non-internal) properties: get
and put, corresponding to retrieval and assignment, respectively.
And
If the value of an attribute is not explicitly specified by this
specification for a named property, the default value defined in Table
7 is used.
In Javascript strict mode
Deleting an undeletable property is not allowed
To make sure that one do not delete such an undeletable property, how do one figure out property X is deletable and property Y is undeletable
The concept behind it is......?
The concept behind this is...?
Property attributes. Every property that has its configurable attribute set to false cannot be deleted (which fails silently in sloppy mode and throws in strict mode).
How to figure out whether a property is deletable?
You can use the Object.getOwnPropertyDescriptor() function to access the attributes as an object:
var isDeletable = Object.getOwnPropertyDescriptor(obj, "propName").configurable;
Notice that this will only work for own properties of obj, not inherited ones; for those you will have to call the function on the respective prototype.
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."
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.