Why I cannot do this?
var MyObject = {}
MyObject.foo = function(){
this.sayhello = function(){
alert('Hello');
}
}
MyObject.foo.sayhello();
Any ideas on how it could be done?
within foo, this references MyObject, which means that after:
MyObject.foo();
you can call:
MyObject.sayhello();
If you want to be able to call MyObject.foo.sayhello(), you need sayhello to be a function on MyObject.foo:
var MyObject = {}
MyObject.foo = function () {...};
MyObject.foo.sayhello = function () {
alert('hello');
}
If you don't need foo to also be a function, you could simply declare:
var MyObject = {
foo: {
sayhello: function () {
alert('Hello');
}
}
}
which would allow you to call:
MyObject.foo.sayhello();
You have to call MyObject.foo() first so that the this.sayhello function actually gets added. Then you should beable to call MyObject.foo.sayhello();
var MyObject = {}
MyObject.foo = {
sayhello: function(){
alert('Hello');
}
}
MyObject.foo.sayhello();
That is because the function does not yet exist. Therefore you must call foo first. What you do is calling the function sayhello from the property foo. But you don't have a property foo. You have a function foo.
But you can also do this and make it chain, like jQuery does:
var MyObject = {}
MyObject.foo = function(){
this.sayhello = function(){
alert('Hello');
}
return this;
}
MyObject.foo().sayhello();
Make a function sayhello inside object foo, so not a chained function. But an object inside an object with a function.
var MyObject = {
foo : {
sayhello : function(){
alert("hello");
}
}
}
MyObject.foo.sayhello(); // Now does work!
Related
I have created an object and am attaching a bunch of functions to the object. I am concerned about how the ordering of the functions effects when I can call my functions. In my example below, I must define my functions first before I can use them. My problem with this is that I cannot call init() immediately until I have defined it. Init() will contain a bunch of other functions that it will need to call, which will have to be placed above init(). So in the end, init() will have to be the very last function defined in my object. I believe this is related to Hoisting.
My question is if there is a way for me to call a function before defining it? Is there some sort of way to create a 'placeholder' function like in C?
https://jsfiddle.net/13hdbysh/1/
(function() {
foo = window.foo || {};
//this will not error
foo.helloWorld = function() {
console.log('helloWorld()');
};
foo.helloWorld();
//this will error
foo.init();
foo.init = function() {
console.log('init()');
};
})();
What you're asking deals with how objects store member data. This can be seen in a weird light because of prototypal inheritance. Javascript by default will parse naked functions before they execute.
Example:
(function() {
init();
function init()
{
console.log("Init");
}
)};
This gets muddied when storing behavior as a member to an object. Because prototypal inheritances dynamic functionality you need to declare your members before accessing them. This is Javascript's main difference from traditional OOP languages.
You mentioned, "is there a way to create a 'placeholder' function like in C." You can, but not in the same way. You can assign it to a naked function and assign that to your object. Look in my example, the hello function.
Alternatively you can store the behavior on the prototype of your object and override it when necessary.
Example:
function hello()
{
console.log("Hello my name is "+this.name);
}
(function() {
var something = function(name) {
this.name = name;
};
something.prototype.initTwo = function() {
console.log("My Name is: "+this.name);
};
var thingOne = new something("Thing One");
thingOne.init = "SomeThing";
var thingTwo = new something("Thing Two");
thingTwo.init = function() {
console.log(this.name);
};
thingTwo.initTwo = function() {
console.log("SomethingTwo is Named: "+this.name);
};
thingTwo.hello = hello;
console.log(thingOne.init);
thingTwo.init();
thingOne.initTwo();
thingTwo.initTwo();
thingTwo.hello();
}) ();
Demo: Fiddle
Documentation on objects in javascript.
Try using similar IIFE pattern
(function() {
foo = window.foo || {};
//this will not error
foo.helloWorld = function() {
console.log('helloWorld()');
};
foo.helloWorld();
//this will error
// foo.init();
foo.init = (function _foo() {
console.log('init()');
this.init = _foo;
return this.init
}).call(foo);
foo.init()
})();
jsfiddle https://jsfiddle.net/13hdbysh/2/
I am not sure why would you wanna call it before it is defined but here is how to do it:
foo = window.foo || { init: function() { } };
How about declaring it as a local variable first.
(function() {
foo = window.foo || {};
//this will not error
foo.helloWorld = function() {
console.log('helloWorld()');
};
foo.helloWorld();
var initFunction = function() {
console.log('init()');
};
//this will no longer error
initFunction();
foo.init = initFunction;
})();
Init() will contain a bunch of other functions that it will need to call, which will have to be placed above init().
You are operating under a misapprehension.
A function must be defined before you call it, not before you define another function which will call it later.
Just define all your functions and then start calling them.
(function() {
foo = window.foo || {};
foo.helloWorld = function() {
console.log('helloWorld()');
};
foo.init = function() {
console.log('init()');
};
foo.init();
foo.helloWorld();
})();
As far as hoisting is concerned, function declarations (you only have function expressions) are hoisted, but they create locally scoped variables, not object properties. You would have to assign them to object properties before you could call them as such, and that assignment wouldn't be hoisted.
It's throwing an error because you're calling the method init() before it's declared.
This way will works
foo.init = function() {
console.log('init()');
};
foo.init();
Since foo is an object, you can put those functions into an object so that will be assigned to foo once window.foo is null
(function() {
foo = window.foo || {
helloWorld: function() {
console.log('helloWorld()');
},
init: function() {
console.log('init()');
}
};
//this will not error
foo.helloWorld();
foo.init()
})();
my problem seems to be that my object function is not visible if i call it from within an object of functions. Example Code:
function foo()
{
this.bar = function()
{
alert("hit me!");
}
this.sna = {
fu: function ()
{
this.bar();
}
};
}
this seems to refer to sna instead of foo. How do i adress foo? this.parent does not work.
Use a variable to refer to this(Foo). See this - JavaScript | MDN
function Foo() {
this.bar = function() {
console.log("hit me!");
};
var that = this;
this.sna = {
fu: function() {
that.bar();
}
};
}
var foo = new Foo();
foo.bar();
foo.sna.fu();
One option is to add a reference to this:
function foo() {
var _t = this;
this.bar = function() { };
this.child = {
this.foo = function() {
_t.bar():
};
};
}
I have a javascript object from which I created from a constructor.
var obj = new Obj();
It has several functions but I wish to also use it as follows;
obj();
Obj is defined as:
function obj() {
this.blah = function () {
};
}
How can I do this?
It would be easier to have a function you call which returns an arbitrary function that is treated as both an object and a function. Each one would be unique, and you would not need to use new.
function Obj() {
var ret = function(){
console.log('Hello');
};
ret.blah = function () {
console.log('World');
};
return ret;
}
var obj = Obj();
obj();//Hello
obj.blah();//World
You can create properties on function objects. For instance, if you have the function
function foo() {
return "bar";
}
You can set a property on foo.
foo.baz = 42;
So now you can call foo and get the result "bar", and you can access its baz property.
I think you are looking for 'closure' here.
Try:
function MyObject(/* constructor params */) {
//assign properties to 'this'
return function() {
return this; //<== placeholder implementation
}.bind(this);
}
var obj1 = new MyObject();
Now if you do console.log(obj1) you will see function() { [...] } and you will be able to do obj1() to execute your function.
As a bonus in the code above, I also added this binding in the 'closure' as you will need it in most cases that you are doing anything interesting.
I have one class with 2 privileged methods :
function ABC() {
this.methodA = function(){
}
this.methodB = function(){
}
}
Is it possible to call methodA inside methodB, if so how to call that?
Yes, but you need a reference to it. If methodB will always be called with the same context, then you can just call methodA from methodB using this.methodA();:
var a = new ABC;
a.methodB(); // Correctly calls methodA();
var func = a.methodB;
func(); // Fails because `this` is not referring to `a` anymore
It will work both ways if you do something like this:
function ABC() {
var methodA = this.methodA = function(){
}
this.methodB = function(){
methodA();
}
}
function ABC() {
var self = this;
this.methodA = function(){
}
this.methodB = function(){
self.methodA();
}
}
var Foo = (function () {
var foo = function() { };
var privateMethod = function(){ };
foo.prototype = {
init: function() {
console.log(this.privateMethod); //undefined
}
};
return foo;
})();
I know that I can access privateMethod directly without using the this pointer. But since I come from the c# world, I would like to use it for readability purposes.
Is there any way to reference my "private methods" using a pointer?
You can't. You can only use this to refer to "public" methods. If you really want to use a something.method notation, you could use:
var Foo = (function () {
var foo = function() { };
var private = {
privateMethod : function(){ };
}
foo.prototype = {
init: function() {
console.log(private.privateMethod);
}
};
return foo;
})();
privateMethod is not specific to each instance of foo. Just reference it without the this. qualifier—although you probably want to log the results of a function call, not the function itself:
console.log(privateMethod());