I accidentally missing this keyword inside setter, getter methods. It leads to some weird bugs: (tested with Chrome, Firefox)
Case 1:
let user = {
name: "John",
set fullName(value) {
name = value;
},
get fullName() {
return name;
}
};
user.fullName // ""
user.fullName = "Batman"
user.fullName // "Batman"
user.name // "John"
Why is property name still "John" ? Where did "Batman" come from?
Case 2: change variable name of the above code, something happens:
let user = {
anythingButName: "John",
set fullName(value) {
anythingButName = value;
},
get fullName() {
return anythingButName;
}
user.fullName // anythingButName is not defined at Object.get fullName [as fullName]...
};
Can't use any name but the word name for the variable in above code. I don't know why?
Both cases are equal. What happens:
let user = {
name: "John",
set fullName(value) {
name = value;//sets window.name to *value*
},
get fullName() {
return name;//returns window.name
}
};
console.log(
user.fullName,// window.name is "" by default
window.name,
user.fullName = "Batman", //=> window.name
window.name,
user.fullName, // "Batman" ==window.name
user.name // "John" //what you really wanted
);
It works ( not really ) just with name as window.name is a default property and therefore set to "" at the beginning.
You can check in your second case:
console.log(
user.fullName, // undefined yet
user.fullName="test",
user.fullName // test
);
Related
what could i do to assign the value of firstName's property to lastName's?
const user = {
firstName: "Someone",
lastName: this.firstName,
};
console.log(user.lastName);
// outputs undefined
Using a getter:
const user = {
firstName: "Someone",
get lastName() { return this.firstName; }
};
console.log(user.lastName);
I have a 'getData' function which gets passed a 'data' variable. Inside the function I'm trying to access an object 'data.someObject' which may or may not exist because it comes from an outside library.
What is the best approach to check if it does exist before trying to use it? Also see I'm using object destructuring here aswell.
const getData = (data) => {
const { name, age } = data.someObject; // someObject may or may not exist
console.log(name, age);
}
I thought doing this might work:
const { name, age } = data.someObject || {};
But I wasn't sure if that would throw an error.
Thanks
You can use || & if required provide default values while destructuring.
function print(user) {
const { fname = "Anonymous", lname = "Panda" } = user.fullname || {};
console.log(`Hello ${fname} ${lname}`);
}
print({ fullname: { fname: "John", lname: "Doe" } });
print({});
print({ fullname: null });
Personally I would put an if statement:
const getData = (data) => {
if (data.someObject == null) {
// Here you can return, throw an error or do anything else you might need
}
const { name, age } = data.someObject; // someObject may or may not exist
console.log(name, age);
}
If I have the following code:
const person = {
name: "Tom",
isHuman: true,
kill() {
// do stuff
}
};
Object.create(person);
How would I access the object or remove/destroy it? I understand I could do something like:
const me = Object.create(person);
me.name = "Bob";
..but that's not what I'm looking for. I don't want to assign it.
Likewise, how would I access the method kill() without first assigning it (e.g. me.kill();?
you can easily delete a created object without var let or const :
const person = {
name: "Tom",
isHuman: true,
};
me = Object.create(person);
delete me
// `me` is removed, and become not defined
// console.log(me) throws an error.
Javascript use a garbage collector, you can use it to delete objects. An object, or a data not referenced, will be deleted :
const person = {
name: "Tom",
isHuman: true,
};
let me = Object.create(person);
me = null
// { name: "Tom", ... } become unreachable, garbage remove it from the memory.
When you use const, you can't assign a new value, you can't delete this value/object/data. But you can clear it with something like this :
const person = {
name: "Tom",
isHuman: true,
kill() {
delete this.name
delete this.isHuman
}
};
const me = Object.create(person);
console.log(person.name) // "Tom"
// delete me // delete nothing
// me = null // throws an error, because you can't assign new value to a const
person.kill()
console.log(person.name) // undefined
console.log(person.isHuman) // undefined
An nice article about javascript's garbage collector
Var, Let ou Const
When you:
const person = {}
you are creating the object(and not a class) person. So to access the method kill you only need to
person.kill();
But i think you want create a class, in this case you can:
class Person {
name = "Tom";
isHuman = true;
kill(){
}
}
const me = new Person();
me.name = "Bob";
me.kill();
Or without using class you can
const createPerson = () => ({
name: "Tom",
isHuman: true,
kill: () => {
//do stuff here
}
});
const me = createPerson();
me.name = "Bob";
me.kill();
An object 'person' has a private variable 'name'. This private variable cannot be updated directly using object reference.
Used IIFE for tackling this. IIFE will return 'name' variable, 'get' and 'update' methods for getting the name and updating it respectively.
const person = (function () {
let name;
var obj = {};
init();
function init() {
name = 'dravid';
}
function getName() {
return name;
}
function modifyName(newName) {
name = newName;
}
Object.defineProperties(obj, {
'name': {
value: name,
writable: false
},
'get': {
value: getName,
writable: false
},
'update': {
value: modifyName,
writable: false
}
});
return obj;
})();
Let's see below what this code is doing.
person.name // returns 'dravid'
person.name = 'dhoni'
person.name // still returns 'dravid'
Now, few more...
person.get() // returns 'dravid'
person.update('dhoni')
person.get() // returns 'dhoni'
Above is pretty much what is required, except for a confusion.
person.name // still returns 'dravid' instead of 'dhoni'
Why such behavior?
Here's the link! to the working code.
The values name and person.name are not the same or equal. When you execute Object.defineProperties and return obj you're setting the default value of person.name equal to name. But when you call person.update you are changing the variable name. You are NOT changing the object key person.name. If you want to change person.name you need to change your modifyName method.
function modifyName(newName) {
obj.name = newName;
}
function x({ name = 'abc' }) {
console.log(name);
}
x({ name: null })
How to provide default value for above case which handles all falsey value for name? I was expecting that when name: null will be replaced by abc but apparently not the case? It's only working in the below case
function x({ name = 'abc' }) {
console.log(name);
}
x({ })
Wondering if it's possible to provide default value for all falsey value? Of course we can check for the condition explicitly but wondering if there is any alternatives
Default parameter values are only applied when the value is undefined. You'd have to implement such logic yourself.
function x({name}) {
if (!name) {
name = 'abc';
}
console.log(name);
}
x({ name: null })
null is intentional, undefined is not.
In other words, providing null means the value is null, so 'abc' will not be set as the default value.
This should do the trick:
function x({ name }) {
!(!!name) && (name = 'abc');
console.log(name);
}
x({ name: null })
How does redefining suits you in case, when the value was null?
function x({ name }) {
name = name ? name : 'abc';
console.log(name);
}
x({ name: null });
x({ name: 'asd' });