JavaScript refer to a method inside a method? - javascript

Ok, just solved one problem where this refered to the wrong scope. Now I have another problem.
So I want to call a method that is inside a method. But I do not know how, check this source:
function someObj() {
var self = this;
this.someMethod1 = function() {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function() {
self.someMethod2.methodMethod();
//I want this.someMethod2.methodMethod() to be called
//...but I get an big error instead. Is it even possible?
//this.someMethod2() works fine.
};
};
this.someMethod2 = function() {
this.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
alert('NO, NOT THIS!');
};
}
Error msg:
Uncaught TypeError: Object function () { ...

With your code, someMethod2 would need to execute first for the function expression to be assigned. Even then, it would be assigned to the parent instance.
Bearing in mind that all functions are objects in JavaScript, this is what you want instead:
this.someMethod2 = function() {
alert('NO, NOT THIS!');
};
this.someMethod2.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};

You are trying to use an object accessor on a function. If you want it to work in this way, you need to return an object literal from your call to the "outer" function.
this.someMethod2 = function() {
return {
methodMethod: function() {
alert('THIS IS THE ONE I WANTED!');
}
}
};
You can then chain the call. self.someMethod2().methodMethod();

While this is not directly possible, you can pass a "command" to the outer function to tell it to execute the inner function. But, are you sure this is what you really need? Perhaps you should use objects instead of functions here. But here's the "command" way:
this.someMethod2 = function(cmd) {
var methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
if (cmd === "methodMethod") {
methodMethod();
return;
}
alert('NO, NOT THIS!');
};

function someObj() {
var self = this;
this.someMethod1 = function () {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function () {
self.someMethod2().methodMethod();
};
};
this.someMethod2 = function () {
this.methodMethod = function () {
alert('THIS IS THE ONE I WANTED!');
};
//return this for chain method.
return this;
};
}

trying
function someObj() {
var self = this;
this.someMethod1 = function() {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function() {
self.someMethod2().methodMethod();
};
this.someMethod2 = function() {
this.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
alert('NO, NOT THIS!');
return this;
};
}
Also if you use prototype then
function someObj() {
var self = this;
this.someMethod1 = function() {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function() {
self.someMethod2.methodMethod();//['methodMethod']();
};
};
this.someMethod2 = function() {
};
this.someMethod2.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
};
But the method methodMethod is static

Related

Access to function through this

var Application;
(function (Application, PhotonSdk) {
(function(Photon) {
Photon.PeerManager = (function () {
var $this;
function PeerManager() {
$this = this;
this.currentStatus = PhotonSdk.PhotonPeer.StatusCodes.connectClosed;
this.peer = new PhotonSdk.PhotonPeer("ws://localhost:9090");
this.peer.addPeerStatusListener(PhotonSdk.PhotonPeer.StatusCodes.connecting, this._onConnecting);
this.peer.addPeerStatusListener(PhotonSdk.PhotonPeer.StatusCodes.connect, this._onConnect);
}
PeerManager.prototype.establishConnection = function() {
this.peer.connect();
console.log("Photon is establishing connection.");
};
PeerManager.prototype._onConnecting = function() {
this.currentStatus = PhotonSdk.PhotonPeer.StatusCodes.connecting;
PeerManager.prototype._logConnectionState(this.currentStatus); //It work
};
PeerManager.prototype._onConnect = function () {
this.currentStatus = PhotonSdk.PhotonPeer.StatusCodes.connect;
this._logConnectionState(this.currentStatus); //It isn't work :(
};
PeerManager.prototype._logConnectionState = function (state) {
console.log("Photon connection is " + state + ". " + new Date().toTimeString());
};
return PeerManager;
})();
})(Application.Photon || (Application.Photon = {}));
})(Application || (Application = {}), Photon);
If i use this._logConnectionState(this.currentStatus);
i get this._logConnectionState is not a function error, but
PeerManager.prototype._logConnectionState(this.currentStatus);
or
$this._logConnectionState(this.currentStatus);
is work. Why it's happened and how i can do that access through this well doing?
My suggestion is that events _onConnecting and _onConnect are dispatching by PhotonSdk.PhotonPeer instance. Since you have added listeners here:
this.peer.addPeerStatusListener(PhotonSdk.PhotonPeer.StatusCodes.connecting, this._onConnecting);
this.peer.addPeerStatusListener(PhotonSdk.PhotonPeer.StatusCodes.connect, this._onConnect);
So functions are called with wrong this.
Try this:
function PeerManager() {
$this = this;
this.currentStatus = PhotonSdk.PhotonPeer.StatusCodes.connectClosed;
this.peer = new PhotonSdk.PhotonPeer("ws://localhost:9090");
this.peer.addPeerStatusListener(PhotonSdk.PhotonPeer.StatusCodes.connecting, this._onConnecting.bind(this));
this.peer.addPeerStatusListener(PhotonSdk.PhotonPeer.StatusCodes.connect, this._onConnect.bind(this));
}
PeerManager.prototype._onConnect = function () {
this.currentStatus = PhotonSdk.PhotonPeer.StatusCodes.connect;
this._logConnectionState(this.currentStatus); //It isn't work :(
};
Your reference you used
_logConnectionState(this.currentStatus);
on seems to be this:
PeerManager.prototype._onConnect
and not that:
Peer Manager.prototype
basicly this refers to
PeerManager.prototype._onConnect
and
this._logConnectionState
is the same as
PeerManager.prototype._onConnect._logConnectionState
wich is undefined because there is no local value /function for that reference.
As you see "this" only has a local context always being bound to the first object/function it can find while climbing up the scopes.

Geting undefined when passing in a parameter to a Module pattern function

$("#foo").on("click", function() {
amountItems.speek('heey')
})
var amountItems = (function(el) {
// var el = el;
return {
speek: function() {
alert(el)
}
}
}())
This is my first attempt to using a module pattern. basically when foo get's clicked i want the speek method inside the amountItems function to be called and I want to pass the string 'heey' to the method so it should alert 'heey' when foo is clicked. originally i wanted to pass something like $("#foo").text() but either way I get 'undefined'.
can you show me how to work with a jQuery object when it's passed into this type of function?
You just have the parameter for el in the wrong place. This works:
$("#foo").on("click", function() {
amountItems.speek('heey')
})
var amountItems = (function() {
return {
speek: function(el) {
alert(el);
}
}
}())
--edit--
Just in case you were wondering how the whole scope / private variables thing works:
$("#foo").on("click", function() {
amountItems.load('heey');
amountItems.speek();
})
var amountItems = (function() {
var el = ""
return {
load: function(str) {
el = str;
},
speek: function() {
alert(el);
}
}
}())
When you do this:
var amountItems = (function(el) {
// var el = el;
return {
speek: function() {
alert(el)
}
}
}())
You execute a wrapper function and assign amountItems with the inner object.
You don't pass a param(el) when you invoke this and therefore el is undefined.
amountItems is an object with a method called speek that doesn't except params.
The right way to do this is:
var amountItems = {
speek: function(txt) {
alert(txt);
}
};
$("#foo").on("click", function() {
amountItems.speek('heey')
})

Overiding a prototype method

I have a javascript base function like this;
roomBase = function () {
this.go = function(){
alert(1);
}
}
I have a room object like this;
myRoom = function(){
this.go = function(){
alert(456);
}
}
myRoom.prototype = new roomBase();
theRoom = new myRoom();
When I call theRoom.go() I am getting an alert from the prototype. What I want is the alert from the myRoom function instead.
It works fine for me. (it alerts 456)
Are you sure everything is running correctly?
Demo: http://jsfiddle.net/9hWAr/
Code for Demo:
var roomBase = function () {
this.go = function(){
alert(1);
}
}
var myRoom = function(){
this.go = function(){
alert(456);
}
}
myRoom.prototype = new roomBase();
var theRoom = new myRoom();
theRoom.go()

How to return a object method in a jquery event

I am trying to return an object method on the event jQuery.change() of a text field,
here is the code:
var Utente = function(indice){
this.Indice = indice;
this.Dati = new Array();
this.initialize = function() {
this.Dati['stato_civile'] = this.getField('stato_civile').val();
this.onChange('stato_civile',this.checkObbligatorieta);
}
this.getField = function(name) {
return $('#'+indice+name);
}
this.onChange = function(field, func) {
this.getField(field).live('change',function() {
return func.apply();
});
}
this.checkObbligatorieta = function() {
this.Dati['stato_civile'] = this.getField('stato_civile').val();
[...]
}
this.initialize();
}
Using this I get the field "#stato_civile" returns the function this.checkObbligatorieta correctly but it gives me an error:
** this.getField('stato_civile').val() is not a function
I think it's something strictly related with the scope, but I can't figure it out.
That's because you're not invoking func() in the same context as the caller, so this is not bound to the same object.
You can fix the problem by passing this to apply():
this.onChange = function(field, func) {
this.getField(field).live("change", function() {
return func.apply(this);
});
};

JavaScript: Accessing Nested Objects

The code looks like this
function Scripts() {this.FindById = function (id) {
this.FindById.constructor.prototype.value = function () {
return document.getElementById(id).value;
}}}
var Control = new Scripts();
Now when i say Control.FindById("T1").value(). I am not able to get the textInput("T1")'s value.
It seems that your code is a bit more complicated then it should be ;-)
Personally I would write it this way (not tested):
function Scripts() {
this.findById = function(id) {
var el = document.getElementById(id);
return {
value: function() {
return el.value;
}
}
}
}
The findById() now closes over a node and returns an interface that can return its value.
Also, your idea sounds a lot like Singleton, so you wouldn't even need the extra Scripts constructor:
var Control = {
findById: function(id) {
var el = document.getElementById(id);
return {
value: function() {
return el.value;
}
}
}
}
Working example: http://jsfiddle.net/YYkD7/
Try this:
function Scripts() {this.FindById = function (id) {
this.FindById.constructor.prototype.value = function () {
return document.getElementById(id).value
}}}
You didn't close the last "}" :-)

Categories