Adding additional functions to object literals after it has been created - javascript

So I was wondering whether this is the right way to add functions to an object created through object literals.
var person = {
firstname: "default",
lastname: "default",
greet: function () {
return "hi " + this.firstname;
}
}
var me = Object.create(person);
me.myFunction = function() {
return console.log("meow");
};
console.log(me.myFunction());
However it returns an undefined after meow, is there any reason why it would do so?

When you write
return console.log("meow");
you don't return "meow", but the return value of console.log, which is undefined. Modify the code like this:
me.myFunction = function() {
return "meow";
};
console.log(me.myFunction());

console.log() doesn't return any value, so the "fallback" value of the function is undefined.
Since you're returning the return value of console.log and log that again, you get undefined.
All of this has nothing to do with modifying an object or a prototype.

You should return meow within myFunction:
var person = {
firstname: "default",
lastname: "default",
greet: function () {
return "hi " + this.firstname;
}
}
var me = Object.create(person);
me.myFunction = function() {
return "meow";
};
document.write(me.myFunction());

var person = {
firstname: "default",
lastname: "default",
greet: function () {
return "hi " + this.firstname;
}
}
var me = Object.create(person);
me.myFunction = function() {
return console.log("meow");
};
console.log(me.myFunction());
why you return console.log() it's return nothing

Related

Why is my function not producing the desired result?

const character = {
name: 'Simon',
getCharacter() {
return this.name;
}
};
const giveMeTheCharacterNOW = character.getCharacter.bind(character);
console.log('?', giveMeTheCharacterNOW);
the answer should be like "? simon"
// How do you fix this issue?
Function#bind returns a function.
Just call the function.
const
character = {
name: 'Simon',
getCharacter() {
return this.name;
}
},
giveMeTheCharacterNOW = character.getCharacter.bind(character);
console.log('?', giveMeTheCharacterNOW());
const character = {
name: 'Simon',
getCharacter() {
return this.name;
}
};
const giveMeTheCharacterNOW = character.getCharacter();
console.log('?', giveMeTheCharacterNOW);

how to get an object from a closure?

How to get an object from a closure, that's confusion with me, here is the question:
var o = function () {
var person = {
name: 'jonathan',
age: 24
}
return {
run: function (key) {
return person[key]
}
}
}
question: How do i get original person object without changing the source code.
var o = function() {
var person = {
name: 'jonathan',
age: 24
}
return {
run: function(key) {
return person[key]
}
}
}
Object.defineProperty(Object.prototype, "self", {
get() {
return this;
}
});
console.log(o().run("self")); // logs the object
This works as all objects inherit the Object.prototype, therefore you can insert a getter to it, which has access to the object through this, then you can use the exposed run method to execute that getter.
You can get the keys by running
o().run("<keyname>"))
Like that:
var o = function () {
var person = {
name: 'jonathan',
age: 24
}
return {
run: function (key) {
return person[key]
}
}
}
console.log(o().run("name"));
console.log(o().run("age"));
Could just toString the function, pull out the part you need, and eval it to get it as an object. This is pretty fragile though so getting it to work for different cases could be tough.
var o = function () {
var person = {
name: 'jonathan',
age: 24
}
return {
run: function (key) {
return person[key]
}
}
}
var person = eval('(' + o.toString().substr(30, 46) + ')')
console.log(person)
o().run("name")
It will be return "jonathan".
Simply you can make this
<script type="text/javascript">
var o = function () {
var person = {
name: 'jonathan',
age: 24
}
return {
run: function (key) {
return person[key]
}
}
}
let a = new o;
alert(a.run('name'));
</script>

Getters are not working in JavaScript

I`m trying to figure out what is getters and setters in JavaScript.
Here is my object
function User(fullName) {
this.fullName = fullName;
Object.defineProperties(this,{
firstName :{
get: function(){
return this.fullName.split(" ")[0];
},
set :function(value){
this.firstName = value;
}
},
lastName:{
get: function(){
this.lastName = this.fullName.split(" ")[1];
},
set: function(value){
this.lastName = value;
}
},
fullName :{
set: function(value){
this.fullName = value;
}
}
});
}
Then creates a new user:
var user = new User("New User");
But when I`m trying to get the firstName property like
alert( user.firstName )
it throw an error "Cannot read property 'split' of undefined".
What may cause the problem? It looks like 'this' is not visible inside get function, but as I understand it should. Thanks!
You don't need a setter for fullName as direct assignment will work.
function User(fullName) {
this.fullName = fullName || '';
Object.defineProperties(this, {
firstName: {
get: function() {
return this.fullName.split(" ")[0];
},
set: function(value) {
this.firstName = value; // NOTE: This will throw an error
}
},
lastName: {
get: function() {
return this.fullName.split(" ")[1];
},
set: function(value) {
this.lastName = value; // NOTE: This will throw an error
}
}
});
}
var joe = new User('John Doe');
var jane = new User('Jane Dane');
jane.fullName = 'Jane Doe';
document.write(
'<pre>' + joe.firstName + '</pre>' +
'<pre>' + jane.lastName + '</pre>'
);
However, as noted in the code comments above you can't set a property on this to the same name as a defined property with a setter. For example:
// defining `firstName`
firstName: {
...
set: function(value) {
this.firstName = value; // NOTE: This will throw an error
}
This operation will cause a recursion stack error as it will continuously try to update firstName since this.firstName is a setter.
To avoid this you could use local scoped variables inside the constructor function and do something like:
function User(fullName) {
var firstName;
var lastName;
Object.defineProperties(this, {
firstName: {
get: function() {
return firstName;
},
set: function(value) {
return (firstName = value);
}
},
lastName: {
get: function() {
return lastName;
},
set: function(value) {
return (lastName = value);
}
},
fullName: {
get: function() {
return firstName + ' ' + lastName;
},
set: function(value) {
var names = value && value.split(' ');
firstName = names[0];
lastName = names[1];
}
}
});
if (fullName) {
this.fullName = fullName;
}
}
var joe = new User('John Doe');
var jane = new User('Jane Dane');
jane.lastName = 'Doe';
document.write(
'<pre>' + joe.firstName + '</pre>' +
'<pre>' + jane.lastName + '</pre>'
);
Some issues/changes needed to your code:
this.fullName.split(" ")[0]; => will try to invoke the getFullName since fullName is defined as a property. Since you have not defined getFullName this results in an error
Say you go ahead and define a getter for fullName:
get: function() {
return this.fullName;
}
This will throw a stackoverflow since this.fullName ends up recursively calling getFullName()
The right way to use it would be (of course update the setters to do something useful):
function User(fullName) {
this.fullName = fullName;
Object.defineProperties(this, {
firstName: {
get: function () {
return this.fullName.split(" ")[0];
},
set: function (value) {
this.firstName = value;
}
},
lastName: {
get: function () {
return this.fullName.split(" ")[1];
},
set: function (value) {
this.lastName = value;
}
}
});
}
var user = new User("New User");
alert( user.firstName );
fullName does not have a getter so it return undefined
get
A function which serves as a getter for the property, or undefined if there is no getter. The function return will be used as the value of property.
Defaults to undefined.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description

Object.defineProperty and return values

I'm playing around with a javascript object that defines some getters and setters using the Object.defineProperty method.
function User() {
var _username;
var _id;
Object.defineProperty(User, 'id', {
get: function() {
return _username;
}
});
Object.defineProperty(User, 'username', {
get: function() {
return _username;
},
set: function(username) {
this._username = username;
}
});
}
For one of the properties (id), I only want a getter. Originally I had a typo and it was returning the value of _username, but I quickly realized that the above did not work. Just for curiosity sake though, I'm trying to understand why it didn't work as expected. If I did the following:
var u = new User();
u.username = 'bob';
alert(u.username);
alert(u.id);
the last statement would alert undefined instead of bob. Why is that? And is there a way to get it to return another property?
You must define the properties on this instead of the constructor function
function User(params) {
var _username;
Object.defineProperty(this, 'id', {
get: function() {
return _username;
}
});
Object.defineProperty(this, 'username', {
get: function() {
return _username;
},
set: function(username) {
_username = username;
}
});
if (params && params.username) {
this.username = params.username;
}
}
User.prototype.stringify = function () {
return JSON.stringify({ username: this.username});
}

(Partial) Extending "functions" in javascript?

I have this code...
var my = {
helpers: {
getName: function() {
return 'John Doe';
}
}
}
// in another file...
var my = {
helpers: {
getAge: function() {
return '40';
}
}
}
// Test...
$("#myDiv").html(my.helpers.getName + " " + my.helpers.getAge);
http://jsfiddle.net/MojoDK/8cmV7/
... but getName is undefined.
I was hoping javascript was smart enough to merge it into this...
var my = {
helpers: {
getName: function() {
return 'John Doe';
},
getAge: function() {
return '40';
}
}
}
How do I extend a method (or what it's called) like above? I have several "helper" files, that needs to "merge".
Redundancy is good for this:
my = window.my || {};
my.helpers = my.helpers || {};
my.helpers.getAge = function() {
return 40;
};
Demo of it in action
You can also use http://api.jquery.com/jquery.extend
as in:
var my = {
getName: function() {}
};
$.extend(my, {
getAge: function() {
}
});
Demo: http://jsfiddle.net/7KW3H/

Categories

Resources