Currently trying to delete an object within another object using the delete keyword as I've seen all around the web. The object I'm using is similar to the one below:
object = { NAME: {hello: 3838383, goodbye: 3474737}, NAME2: {hello: 3838383, goodbye: 3474737} }
Trying:
delete object.NAME
But I continually get: Cannot delete property 'NAME' of [object Object]. Any ideas?
It sounds like NAME is a non-configurable property. That means you can't delete it I'm afraid, as deleting (removing) a property counts as "configuring" it (as does changing the configurable flag on the property).
You can see what the configuration of the property is by using Object.getOwnPropertyDescriptor. In your case it probably will either not show a configurable property at all (because false is the default) or more likely it'll show configurable: false.
Here's an example which shows using getOwnPropertyDescriptor and demonstrates the error you're getting:
"use strict";
const object = { };
Object.defineProperty(object, "NAME", {
value: {hello: 3838383, goodbye: 3474737},
configurable: false,
writable: true
});
console.log(Object.getOwnPropertyDescriptor(object, "NAME"));
delete object.NAME;
If the property is writable, you can assign some other value to itm, such as null or undefined:
object.NAME = null;
But if it's also non-writable, you can't do that, either.
As a final resort, you could create a new object and only copy the properties to it that you want, and assign that new object to the variable or property you're using to refer to the object. For instance:
object = Object.fromEntries(
Object.entries(object)
.filter(([key]) => key !== "NAME")
);
Live Example:
"use strict";
let object = {
NAME2: {hello: 3838383, goodbye: 3474737}
};
Object.defineProperty(object, "NAME", {
value: {hello: 3838383, goodbye: 3474737},
configurable: false, // Just here for emphasis, false is the default
writable: false // same
});
console.log(Object.getOwnPropertyDescriptor(object, "NAME"));
// Can't do this: delete object.NAME;
object = Object.fromEntries(
Object.entries(object)
.filter(([key]) => key !== "NAME")
);
console.log(object);
.as-console-wrapper {
max-height: 100% !important;
}
Related
let obj = {windows : 10,wheels : 100,seats : 99};
console.log(Object.getOwnPropertyDescriptor(obj, 'wheels'))
Output:
Object { value: 100, writable: true, enumerable: true, configurable: true }
I read on an article that the default values of an object's descriptor are false, but the following code shows otherwise. Can someone tell me the mistake?
I read on an article that the default values of an object's descriptor are false...
That's only when you call Object.defineProperty or its cousin defineProperties (or use the second argument of Object.create), the defaults for the flags in the descriptor object are all false:
let obj = {};
Object.defineProperty(obj, "wheels", {
value: 100,
});
console.log(Object.getOwnPropertyDescriptor(obj, "wheels"))
When you create a property via direct assignment as you are in the question, they all default to true.
Somehow I can read the property of a getter, but I can't delete it.
(I can delete getters/setters defined w/o using Object.defineProperties)
var hello = {
get num() {
return 123;
}
}
delete hello.num;
// returns true
However,
var hello = {};
Object.defineProperties(hello, {
num: {
get() {
return 123;
}
}
}
delete hello.num;
// returns false
The problem is that using the .defineProperties their is a property called writable
By default, it is set to False set it to true there is also a property called configurable
set it to true as well You can see the following code example to achieve this
'use strict'
Object.defineProperty(window, 'hello',{
get: ()=>"hello to you!",
configurable: true //make this true
and for the writeable property you can set it like this:
Object.defineProperty(obj, 'key', {
enumerable: false,
configurable: True,
writable: True,
value: 'static'
});
I'm trying to check the below,
USECASE: 1
var obj = {};
_.isEmpty(obj); ====> returns true
USECASE: 2
var obj = { model: undefined, vendor: undefined, type: undefined }
_.isEmpty(obj); ====> returns false
In usecase 2 is there any other function that i could leverage to return true since all the properties are undefined.
I referred this http://www.ericfeminella.com/blog/2012/08/18/determining-if-an-object-is-empty-with-underscore-lo-dash/ but not sure how to implement it without modifying the native method.
Without Underscore:
const objEmpty = obj => Object.keys(obj).every(key => obj[key] === undefined);
Will accept an object and return true if the object is empty (no properties) or if all the properties have undefined value. Else returns false.
You could use every and pass in the isUndefined predicate:
var obj = { model: undefined, vendor: undefined, type: undefined }
var result = _.every(obj, _.isUndefined);
Alternatively you could omit the undefined values and check whether the object is empty:
var result = _.isEmpty(_.omit(obj, _.isUndefined));
According to the spec when adding a javascript object property, the following defaults will be applied to property descriptors:
configurable: false
enumerable: false
writable: false
However when assigning an object property using the following (very popular) dot notation method they all default to true.
myObject = {};
myObject.a = 1;
Why is this?
Apparently - again according to a non-obvious part of the spec - it is due to the way the object property is defined.
See here
If an object property is defined using the dot notation method:
var myObject={};
myObject.a=1;
then all property descriptors default to true
If an object property is defined using the bracket notation method:
var myObject = {};
myObject["a"] = 1;
then all property descriptors default to true
However if an object property is defined using the defineProperty method:
var myObject={};
Object.defineProperty(myObject, 'a', { value: 1 });
any undefined descriptors default to false.
See an example in this jsfiddle
This is an issue that confuse a lot of new developers/programmers/engineers. There are two methods that contribute to this issue in the MDN. If you look at the Object.getOwnPropertyDescriptor() method in the MDN. It says that writable, enumerable, and configurable all default to false, but when you use the method all will return true (Yes, they are false by default).
Example:
let user = {
name: "John"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log( JSON.stringify(descriptor, null, 2 ) );
/* property descriptor:
{
"value": "John",
"writable": true,
"enumerable": true,
"configurable": true
}
*/
Now, If you use the Object.defineProperty() method then you will see that the special property attributes are set to false by default. In the example below you will notice, because I didn't set an special attributes all of the properties are false by default.
Example:
let user = {};
Object.defineProperty(user, "name", {
value: "John"
});
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log( JSON.stringify(descriptor, null, 2 ) );
/*
{
"value": "John",
"writable": false,
"enumerable": false,
"configurable": false
}
*/
I know this is confusing for most people that are new to JavaScript, but I wouldn't try to overthink it. Keep it Simple...
Through the following code I can get a plugin object in chrome browser:
nav = window.navigator;
detectPlugin = function(pluginName, mimeType) {
return nav.plugins && nav.plugins[pluginName] && nav.mimeTypes && nav.mimeTypes[mimeType] && nav.mimeTypes[mimeType].enabledPlugin ? nav.plugins[pluginName] : false;
};
obj = detectPlugin('Shockwave Flash', 'application/x-shockwave-flash');
And I can see the obj's properties through
Object.keys(obj)
which is
["0", "1", "length", "description", "filename", "name"]
or I can see these through chrome Console:
Plugin {0: MimeType, 1: MimeType, length: 2, description: "Shockwave Flash 13.0 r0", filename: "libpepflashplayer.so", name: "Shockwave Flash", item: function…}
And here is something that I don't understand, if I input
obj['application/x-shockwave-flash']
I get this
MimeType {enabledPlugin: Plugin, description: "Shockwave Flash", suffixes: "swf", type: "application/x-shockwave-flash"}
I know obj[0] is the property of 'MimeType', but I don't know why "obj['application/x-shockwave-flash']" can get this.
Any help would be great!
Object.keys only returns
a given object's own enumerable properties
i.e. if it's inherited or non-enumberable, you won't see it
What does it mean for a property to be enumerable?
In JavaScript, you can think of it as similar to meaning "the property is visible to loops"
What does it mean for a property to be inherited?
An Object inherits properties and methods from it's prototype, this means you can have very generic Objects, e.g. {} instanceof Object; // true and very complicated ones like d = new Date(), where d instanceof Date; // true but it still has everything the from the more generic Object, i.e. d instanceof Object; // true
Consider this (assuming IE 9+)
var o = {};
Object.defineProperty(o, 'foo', {value:"bar", enumerable:false});
Object.keys(o); // []
o.foo; // "bar"
And
navigator.plugins[0].hasOwnProperty('application/x-shockwave-flash'); // true
Object.getOwnPropertyDescriptor(
navigator.plugins[0],
'application/x-shockwave-flash'
);
//Object {value: MimeType, writable: true, enumerable: false, configurable: true}
The MDN page here may be helpful in understanding enumerability and ownership