I am wondering why JSON.stringify(this.Master.Func) returns 'undefined' instead of function() { ... }.
Function itself executes by adding ().
JSfiddle: http://jsfiddle.net/t4ngY/
CODE
var $ = {}; // some global
var Master =
{
property: 'Property',
Func: function()
{
console.log('I am Func inside Master');
},
PassToGlobal: function()
{
$.master = this;
}
};
Master.PassToGlobal();
var Slave =
{
Master: $.master,
ShowFunc: function()
{
console.log(JSON.stringify(this.Master.Func)); //returns undef
this.Master.Func(); //prints `I am Func inside Master`
}
}
Slave.ShowFunc();
if you want see function text you can simply call toString method like this
console.log(this.Master.Func.toString());
Related
How would you override a function on a javascript object when the function is on another object within the parent object.
Example:
function TestingABC() {
this.events = { finish: function() { console.log("FINISHED"); } };
}
function TestingXYZ() {
TestingABC.call(this);
}
TestingXYZ.prototype = Object.create(TestingABC.prototype);
How would I override the events.finish function on TestingXYZ to run the parent (TestingABC) code along with some new code that I need to write?
Because the events object is property of the instance, not on the prototype, you could employ a technique similar to monkey patching, where you store a reference to the current function, then override the current function with one that can call the old one in addition to doing other stuff.
e.g.
function TestingABC() {
this.events = { finish: function() { console.log("FINISHED"); } };
}
function TestingXYZ() {
TestingABC.call(this);
var superEvents = this.events;
this.events = {
finish: function () {
superEvents.finish();
doMyStuff();
}
};
}
TestingXYZ.prototype = Object.create(TestingABC.prototype);
.events is an instantiated property of the TestingABC() constructor - so you can amend the value once you have an instantiation of it.
Perhaps something like this is what you're after?...
function TestingABC() {
this.events = {
finish: function() {
console.log('ABC FINISHED');
},
other: function() {
console.log('ABC OTHER');
}
};
}
function TestingXYZ() {
TestingABC.call(this);
}
TestingXYZ.prototype = Object.create(TestingABC.prototype);
TestingXYZ.prototype.callEvents = function() {
this.events.finish();
this.events.other();
}
var test1 = new TestingABC();
var test2 = new TestingXYZ();
test2.events.finish = function() {
console.log('XYZ FINISHED');
};
test1.events.finish();
test1.events.other();
//-> ABC FINISHED
//-> ABC OTHER
test2.callEvents();
//-> XYZ FINISHED
//-> ABC OTHER
I am trying to create my object through a function, but I am unable to figure out the syntax for the getter function.
var myObject =
{
0:123,
get a()
{
return this[0];
}
}
console.log("This works: " + myObject.a);
function test()
{
this[0] = 123;
// error
this.a = get function()
{
return this[0];
};
}
var myTest = new test();
console.log(myTest.a);
Within the test function, the assignment of the get function throws a missing semicolon error and if I remove the keyword "function", it says that get is not defined.
How can I assign a getter function to the current object within my function?
You could try something like this:
var myObject =
{
0:123,
get a()
{
return this[0];
}
}
console.log("This works: " + myObject.a);
function test()
{
this[0] = 123;
Object.defineProperties(this, {"a": { get: function () {
return this[0];
}}});
}
var myTest = new test();
console.log(myTest.a);
Maybe this will work for you :
function test()
{
this[0] = 123;
Object.defineProperty(this, "a", { get: function () { return this[0]; } });
}
Suppose I have a variable that contains the name of a function I want to run, I can run it by using window, like so;
var func = "myFunc",
myFunc = function(){ ... };
window[func](); // run the function in the func var
However, this doesn't work if the intended function is deep inside an object;
var obj = {
foo: {
hey: function(){ ... }
}
};
obj.foo.hey(); // this runs
var func = "obj.foo.hey";
window[func](); // this doesn't
I could use eval(), but I wonder if it's possible to avoid that, so as to not introduce the many security considerations that eval() comes with.
How can I run a function specified in a variable, when the function is in an object as described above?
You could iterate the splitted func and return the result of an walked object.
function getValue(object, path) {
return path.split('.').reduce(function (o, k) {
return (o || {})[k];
}, object);
}
var obj = { foo: { hey: function () { console.log('hey'); } } },
func = "obj.foo.hey";
getValue(window, func)();
(getValue(window, 'bar') || function () {})(); // default function, prevent exception
You can's pass nested properties under a single string. It must be done dynamically like.
var obj = {
foo: {
hey: function(){console.log("i run")}
}
};
obj.foo.hey(); // this runs
var route = ["obj","foo","hey"],
func = route.reduce((f,r) => f[r], window);
func()
Playing around with some JS tests and I'm trying to instantiate some nested objects in my v namespace. As you'll see below, ClassA and ClassB work as expected. When I try and nest some objects under another property (myCustomProperty) I start running into issues! Could someone explain?
Below is the original code:
var v = (v) ? v : {};
v.someClassA = (function() {
this.hello = function() {
console.log("Class A Hello!");
}
});
v.someClassB = (function() {
this.hello = function() {
console.log("Class B Hello!");
}
});
// this all works!
var myClassA = new v.someClassA();
var myClassB = new v.someClassB();
v.myCustomProperty = (function() {
function someClassC() {
this.hello = function() {
console.log('C');
}
}
function someClassD() {
this.hello = function() {
console.log('D');
}
}
return {
someClassC: someClassC,
someClassD: someClassD
}
});
// Uncaught TypeError: v.myCustomProperty.someClassC is not a function! Why?
var myClassC = new v.myCustomProperty.someClassC();
var myClassD = new v.myCustomProperty.someClassD();
myClassA.hello();
myClassB.hello();
myClassC.hello();
myClassD.hello();
If I change my declaration of v.myCustomProperty to use object literal notation, then it ALL WORKS! :
v.myCustomProperty = {
someClassC: function() {
this.hello = function() {
console.log('C');
}
},
someClassD: function() {
this.hello = function() {
console.log('D');
}
}
}
I guess my question really is how would I make this work using the notation in my original snippet? Possible? Horrible practice to do it that way?
Thanks!
v.myCustomProperty is a function that returns an object. You have to call the function first:
new (v.myCustomProperty().someClassC)();
// ^^
Otherwise, v.myCustomProperty.someClassC() tries to access the property someClassC of the function, and we all know (hopefully) that functions don't have such a property.
Or maybe you intended to execute the function immediately and assign the object to myCustomProperty?
v.myCustomProperty = (function() {
// ...
}()); // <- call function
I tried execute this code:
var system = new Object();
(function($) {
$.init = function() {
var o = {
message: function(arg) {
return arg.val;
},
alert: this.message({
val: "Hello, world."
})
};
return o.alert;
};
})(system);
alert(system.init());
but, when I execute it I get error message which tells me that this.message is not a function. Obviously, this not refers to object o itself, and I want to know why.
I found few solutions on stackoverflow where this is always inside function body, but why this can not be outside? Thanks.
Change your code to:
var system = new Object();
(function($) {
$.init = function() {
var o = {
message: function(arg) {
return arg.val;
}
};
o.alert = o.message({
val: "Hello, world."
});
return o.alert;
};
})(system);
system.init()
Yields:
"Hello, world."
In your code this would refer to window in that context. If you want to create an object and refer to it as this - use constructor function, i.e.:
var o = new function(){
...
<here: this == o>
...
}
You can use an anonymous constructor function instead of object literal syntax if you want to reference the object during instantiation.
(function($) {
$.init = function() {
// -----vvv---vvv---constructor function
var o = new function() {
this.message = function(arg) {
return arg.val;
},
this.alert = this.message({
val: "Hello, world."
})
};
return o.alert;
};
})(system);
Because the value of this is only defined within a function when the function is invoked, object literal syntax never changes its value.
So instead we create a function, and invoke it using new so that the value of this in the function is a reference to the new object we're building.
And of course it doesn't need to be anonymous, but if you're only going to use it once, there's no need for a name.