Modern ES6 Approach
You no longer need to specify the function keyword when defining functions inside objects.
First option with named functions:
const myObj = {
myMethod(params) {
// ...do something here
},
myOtherMethod(params) {
// ...do something here
},
nestedObj: {
myNestedMethod(params) {
// ...do something here
}
}
};
Second option with anonymous functions:
const myObj = {
myMethod: (params) => {
// ...do something here
},
myOtherMethod: (params) => {
// ...do something here
},
nestedObj: {
myNestedMethod: (params) => {
// ...do something here
}
}
};
Pre ES6 style:
const myObj = {
myMethod: function myMethod(params) {
// ...do something here
},
myOtherMethod: function myOtherMethod(params) {
// ...do something here
},
nestedObj: {
myNestedMethod: function myNestedMethod(params) {
// ...do something here
}
}
};
Note: In the first example the functions are named and have their own this-context. In the second example, the this-context from outside of the functions is used. In the third example, the functions are not named, but have their own this-context.
So while all methods seem similar, they are a bit different.
you need to define the objects like this :
var argument1 = {
myvar : "12",
mymethod : function(test) { return something; }
}
then call mymethod like:
argument1.mymethod(parameter);
or the deeper version :
var argument1 = {
argument2 : {
mymethod : function(test) { return something; }
}
}
then:
argument1.argument2.mymethod(parameter);
javascript - Using function inside function inside an object - Stack Overflow
javascript - Function inside object - Stack Overflow
javascript - Functions in object literals - Code Review Stack Exchange
Is it possible to let a function access an entire object's properties by passing it a single property?
Videos
I have an object named "subject" and a function named "getDueDate" I would like to call that function inside of a subject object that would return value when called upon an atribute.
var subject = {
name: 'Person',
birth_day: new Date('2017-04-21'),
due_date: getDueDate(subject.birth_day, subject.current_cycle),
current_cycle: 1,
last_water_date: null,
next_water_date: null,
};
var getDueDate = function(birth_day, cycles) {
var result = new Date(birth_day);
console.info('result_ ' + result);
result.setDate(result.getDate() + cycles);
console.info('result_1_ ' + result);
return result;
};when I try to parse subject.due_date I get an error getDueDate undefined, what am I doing wrong or it's not even possible to do that?
function getDueDate (birth_day, cycles) {
const result = new Date(birth_day)
result.setDate(result.getDate() + cycles)
return result
}
const subject = {
name: 'Person',
birth_day: new Date('2017-04-21'),
current_cycle: 1,
due_date: function() {
return getDueDate(this.birth_day, this.current_cycle)
},
last_water_date: null,
next_water_date: null,
}
console.log(subject.due_date())
With a simple work:
var YourClass = function(name,bday,ddate,cc,lwd,nwd){
this.name = name;
this.birth_day: bday;
this.due_date = ddate;
this.current_cycle: cc;
this.last_water_date: lwd;
this.next_water_date: nwd;
}
YourClass.prototype.getDueDate = function(birth_day, cycles) {
var result = new Date(birth_day);
console.info('result_ ' + result);
result.setDate(result.getDate() + cycles);
console.info('result_1_ ' + result);
return result;
};
var obj = new YourClass(...);
This makes you a class in js
Assuming that function_b is called via:
your_module().function_b();
Then you can access the object with this inside function_b.
this.function_a();
If the method gets detached from the object, then you'll lose that connection so it might be worth rewriting the module so you have a reference that doesn't depend on the value of this. For example:
module.exports = function(req, res) {
const my_return_value = {
function_a: function() {
// do something here
},
function_b: function() {
const A = my_return_value.function_a();
}
};
return my_return_value;
}
The code you currently have is not valid JavaScript. You're trying to handle functions as an object inside a function (??).
Here's what you can do: first create the functions outside of module.exports
function funcA(){
console.log('Inside function A!');
}
function funcB(){
funcA();
console.log('inside function B!');
}
This will behave like any two functions would. Calling funcA() will log 'Inside function A!' and calling funcB() will log 'Inside function A!' 'inside function B!' as expected.
You can then export them to be used elsewhere:
exports = {
funcA: funcA,
funcB: funcB
}
Here we are using exports rather than module.exports which is equivalent. The above can be simplified with ES6: {funcA, funcB} since key and value have the same name.
You could use a CSS extension language (like LESS or SCSS) to handle variables, then simply process and use some simple stylesheet.
If you want to stick with JS, I would suggest returning a hash from transform and extending that later, like:
function transform(val) {
return {
"-webkit-transform": "translateY(" + val + "%)",
"-ms-transform": "translateY(" + val + "%)",
"transform": "translateY(" + val + "%)"
}
}
function transformWithOpacity(val) {
var base = transform(val);
base["opacity"] = val;
return base;
}
var num = 50 * (t/h);
$("#header").css(transformWithOpacity(num));
You can use JQuery extend function for this
$("#header").css($.extend({
opacity: 50 * (t/h)
},
tranform(50 * (t/h))
));
Problem 1
Just assign them one at a time, once the object already exists:
ns = {};
ns.a = function (x, y) { return x+y; };
ns.b = ns.a;
To answer specifically whether there's any other workaround if you're dead set on declaring these inside the object literal syntax: no.
Problem 2
Looks good enough to me, though I'd try to avoid using the object's name so deep into its definition.
Consider using prototyping instead.
Problem 1
When creating an object literal, this scoped by whatever function is constructing the object. This allows you to do:
this.foo = 'bar';
var obj = { foo: this.foo };
console.log(obj.foo); // 'bar'
In fact the object doesn't exist until the end of the object literal, so there is no object to reference.
The correct work around for you issue would be like so. Because you cannot use the same value for multiple keys in an object literal.
ns = { a: function() {} };
ns.c = ns.a; // the same function now is on .a and .c
Problem 2
This has nothing to do with scope, but instead context (the value of this). In function invocations, the dot syntax is what provides the this. For example:
obj.someFn() // inside someFn: this === obj
It's the syntax that provides this. So when there is no dot accessor, this defaults to the global object (window in a browser).
The usual work around is to simply save a reference to the current object which is shared with any functions in the same scope.
d: function(x, y) {
var self = this;
var add = function(x, y) {
self.a(x, y);
};
add(3, 4);
}
Or use call or apply to explicitly set the function context, which overrides the default binding of this with whatever object you want.
d: function(x, y) {
var add = function(x, y) {
this.a(x, y);
};
add.call(this, 3, 4);
}