javascript calling parent method from child - javascript

I have the following object:
var party =
{
food:
{
serve: function () {
// I want to call turnOff method from here
}
cleanUp: function () {
}
}
music:
{
turnOff: function () {
}
}
}
So as the comment points out, I want to call the turnOff method from the music object, how can I do this? this refers to the food object but I need to access the music object...

var party =
{
food:
{
serve: function () {
party.music.turnOff();
},
cleanUp: function () {
}
},
music:
{
turnOff: function () {
}
}
}

Use a constructor instead of a literal with a variable referencing the parent object
var party = new (function()
{
var self = this;
this.food =
{
serve: function () {
self.music.turnoff();
},
cleanUp: function () {
}
}
this.music =
{
turnOff: function () {
}
}
})();

Call it as party.music.turnOff().
FYI, your above code block isn't valid. You're missing some commas - after the serve and food closing braces.

Related

How to quick to get everything from destructuring assignment?

For example, I have a object with server functions.
let funs = {
fun1: () => { console.log('fun1') },
fun2: () => { console.log('fun2') },
fun3: () => { console.log('fun3') },
};
then I want to have quick way to use this function set.
class SampleClass {
sampleFun() {
{...funs} // anything similar to it?
fun1();
}
}
It's not possible.
I close alternative is calling that function, using the function call with funs as lexical context.
let funs = {
fun1: () => { console.log('fun1') },
fun2: () => { console.log('fun2') },
fun3: () => { console.log('fun3') },
};
class SampleClass {
sampleFun() {
this.fun1();
this.fun2();
}
}
new SampleClass().sampleFun.call(funs);
You could pull the functions into the namespace of your instance with Object.assign(), then you could call with this.fun1(), etc...
let funs = {
fun1: () => { console.log('fun1') },
fun2: () => { console.log('fun2') },
fun3: () => { console.log('fun3') },
};
class SampleClass {
constructor(funs) {
Object.assign(this, funs)
}
sampleFun() {
this.fun1()
this.fun2()
this.fun3()
}
}
let s = new SampleClass(funs)
s.sampleFun()
There is no way to do that. In other words you are asking for Dynamic variable names which are not possible without using eval(). Here is your code the names of function are in series you can call all using loop.
let funs = {
fun1: () => { console.log('fun1') },
fun2: () => { console.log('fun2') },
fun3: () => { console.log('fun3') },
};
class SampleClass {
constructor(funs) {
Object.assign(this, funs)
}
sampleFun() {
for(let i = 1;i<=3;i++){
this[`fun${i}`]();
}
}
}
let s = new SampleClass(funs)
s.sampleFun()
I think all answers are correct, but I'm actually looking for shortcut form; like what #CertainPerformance said, there is no way to have shortcut expression

Why doesn't the bind() work for a function inside another function which is inside the object?

I have a question about .bind() function.
I have this code and it outputs Window object and I don't understand why. Could you explain to me why bind(this) had no effect on the function?
let vakho = {
name: "salome",
a: function () {
let something = function () {
return this;
}
something.bind(this)
return {
f: function () {
return something();
}
}
},
}
console.log(vakho.a().f())
.bind returns a new function with the attached context. You need to assign the result to the something again.
let vakho = {
name: "salome",
a: function () {
let something = function () {
return this;
};
something = something.bind(this); // Assign to the something
return {
f: function () {
return something();
}
}
},
}
console.log(vakho.a().f());
console.log(vakho.a().f().name);

Calling a private/nested javascript function from an outer scope

I have my javascript code like this . Inside that I have an init() function and in that function I have an options JSON object and in that object I have a function defined as objectselected(). How I call that function in a button click event
I have tried like this WorkFlow.init().options.Objectselected() but it is not working,
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
},
}
How to call that function.
One way around is you can return options and than call it.
init: function () {
var options = {
...your code..}
return options;
},
and call it than
var options = WorkFlow.init();
options.Objectselected();
As it stands, you have no access to options because it's a local variable - that is, local to its scope.
To access its contents, you'll need to return it from init().
Think about it:
WorkFlow.init()
Currently this returns undefined, because your init() returns nothing. You're trying to chain like in jQuery, but that relies on the API always returning the instance. Your path finds a dead-end at init().
To fix this, have init() return options - or at least the part of it you want to access from outside - an "export".
So (basic example)
init: function() {
var options {
my_func: function() { }, //<-- we want outside access to this
private: 'blah' //<-- this can stay private - leave it out of the export
}
//return an export, exposing only what we need to
return {
my_func: options.my_func
}
}
You need to return options as it is inside init function's scope
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
return options;
},
}
And call it as WorkFlow.init().objectSelected();
Building on Patrick's comment, you'd need to return options from the init function:
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
...
options.initialize();
return options;
},
}

How to allow JQuery event handler to access variables in module pattern

var MODULE = (function() {
var app = {
hi: "hi mom", // I can't access this. Oh' what do I do?
onSubmitClick: function() {
$('button').click(function() {
console.log(hi); // I want to access the above hi variable..eeek!
})
},
run: function() {
this.onSubmitClick()
}
}
return app
}());
var newApp = MODULE;
newApp.run();
hi is not a variable, it is a property of the object app
var MODULE = (function () {
var app = {
hi: "hi mom",
onSubmitClick: function () {
$('button').click(function () {
console.log(app.hi); //use the app object and access the property
})
},
run: function () {
this.onSubmitClick()
}
}
return app
}());
var newApp = MODULE;
newApp.run();
Demo: Fiddle
You can do something like this also.
var app = {
hi: "hi mom",
onSubmitClick: function (cthis) {
$('button').click(function () {
alert(cthis.hi); //use the app object and access the property
})
},
run: function () {
this.onSubmitClick(this);
//-------------------^ this is referring app
}
}
Demo

Javascript variable scope

Is it possible for me to call selectCompanyJump(this) internally without calling it from App.site.profile?
Instead of doing App.site.profile.selectStateJump(this); can I do like parent.selectStateJump(this); without reassigning this outside of the .change() call?
$(document).ready(function () {
App.site = function () {
return {
init: function () {
this.profile.init();
},
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
$('select[name="company_id"]', profile).change(function () {
App.site.profile.selectCompanyJump(this);
});
$('select[name="state_id"]', profile).change(function () {
App.site.profile.selectStateJump(this);
});
},
selectCompanyJump: function (select) {
$(select.parent()).submit();
},
selectStateJump: function (select) {
$(select.parent()).submit();
}
}
}()
}
}();
App.site.init();
});
You can reference the "this" scope you want as another variable outside change() function definitions:
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
var self = this;
$('select[name="company_id"]', profile).change(function () {
self.selectCompanyJump(this);
});
$('select[name="state_id"]', profile).change(function () {
self.selectStateJump(this);
});
},
selectCompanyJump: function (select) {
$(select.parent()).submit();
},
selectStateJump: function (select) {
$(select.parent()).submit();
}
}
}()
Assuming that you are just using the select argument of your functions to reference the element that triggered the event you could just pass a pointer to the event binder and then use the this keyword.
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
$('name="state_id"', profile).change(this.selectStateJump);
},
selectStateJump: function () {
$(this).parent().submit();
}
}
you can do the following
$(document).ready(function () {
App.site = function () {
var me = this;
me.selectStateJump = function selectStateJump (select) {
$(select.parent()).submit();
}
return {
....
selectStateJump: selectStateJump
}
and you'll be able to call just me.selectStateJump()
EDIT:
actually below would be enough
$(document).ready(function () {
App.site = function () {
function selectStateJump (select) {
$(select.parent()).submit();
}
return {
method : function(select) {
selectStateJump(select);
}
selectStateJump: selectStateJump
}

Categories