How can I access the super of the super class in JS? - javascript

The code is pretty explanatory. What I am doing is wrong. How can I access the a property of the A object in the onclick event of an object declared inside of an A object method?
function A(){
this.a = 0;
};
A.prototype.myfun= function(){
var b = document.getElementsByClassName("myclassName");
b[0].onclick = function(e){
//How can I get the a property of the A object in here?
this.a = 1;
}
};
Could I somehow pass this as an argument like this?
b[0].onclick = function(e, this){

Since this in a function references to the function itself, you could do 2 things. Pass around the reference, or create a variable you won't overwrite that represents the this
function A(){
this.a = 0;
};
A.prototype.myfun= function(){
var self = this;
var b = document.getElementsByClassName("myclassName");
b[0].onclick = function(e){
self.a = 1;
}
};

Related

Compose functions in the prototype [duplicate]

var Ob = function(){
}
Ob.prototype.add = function(){
inc()
}
Ob.prototype.inc = function(){
alert(' Inc called ');
}
window.onload = function(){
var o = new Ob();
o.add();
}
I would like to call something like this,how can i call, ofcourse i put inc as inner function to add I can do that but without having the inner function. how do i do that ?
It's easy:
Ob.prototype.add = function(){
this.inc()
}
Ob.prototype.inc = function(){
alert(' Inc called ');
}
When you create the instance of Ob properties from prototype are copied to the object. If you want to access the methods of instance from within its another method you could use this.

Can't call variable from another object

I have 2 objects: myObject1 and myObject2.
I am trying to call a private variable from myObject1 using my0bject2 method called increment, but console.log says NaN.
Is there any way to call myObject1 variable directly from myObject2 method? Maybe extend it somehow?
var myObject1 = function() {
var x = 0;
return{}
}();
var myObject2 = function() {
return{
increment: function() {
myObject1.x +=1;
console.log(myObject1.x);
}
}
}();
myObject2.increment();
When you specify var x within myObject1 you are declaring that variable as private. The only thing that has access to that variable are methods within myObject1. As you noted, this variable is private.
You didn't make it clear if you wanted to keep it private or not so I will assume you just want to access it. You could do a couple of things here.
You could attach the variable as an object property of myObject1 via this. this refers to the current scope (myObject1) so by saying this.x within myObject1 you are saying myObject1.x. From that function, you will need to return this so that instances of it can access all of its public properties.
var myObject1 = function() {
this.x = 0;
return this;
}();
var myObject2 = function() {
return {
increment: function() {
myObject1.x +=1;
console.log(myObject1.x);
}
}
}();
myObject2.increment();
You could also just return the properties that you want, in this case x. You have more control over what is returned in this case and you get the same result as above.
var myObject1 = function() {
var x = 0;
return {
x: x,
};
}();
var myObject2 = function() {
return {
increment: function() {
myObject1.x +=1;
console.log(myObject1.x);
}
}
}();
myObject2.increment();
Either way, these methods both expose the x property of myObject1 making it public.
Its because you have to create an instance of the function myObject before you can access its properties,
/* Create an object called myObject which can be instantiated using the new keyword */
var myObject = function() {
/* use 'this.x' to define an internal variable for x */
this.x = 0
};
/* this is where you create a new instance of myObject which will have the 'x' property */
var myObject1 = new myObject();
var myObject2 = function() {
return {
increment: function() {
myObject1.x += 1;
console.log(myObject1.x);
}
}
}();
myObject2.increment();
EDIT: Added comments to the code to explain the important modifications
myObject1 returns an object in which x is its own property. So now you're incrementing one of the property of the object. Earlier, with var x you were assuming to increment property of myObject1 but in fact it was just a local variable for that function which returned your object, i.e. declaring var x in function has no effect whatsoever.
var myObject1 = function() {
return{
x: 0
}
}();
var myObject2 = function() {
return{
increment: function() {
myObject1.x +=1;
console.log(myObject1.x);
}
}
}();
myObject2.increment();
In javascript, there is function scope, that is anything you define with var keyword is accessible within that function body.
Here you are implementing the module pattern. Your functions behave as constructors (or a factory) in your case (returning the object constructed). myObject2 cannot access x as it is defined in another scope and it is not included in the object generated by your first function.
You can return the x variable inside the return object;
var myObject1 = function() {
return{
x: 0
}
}();
That makes it a property on the returned object (that is assigned to myObject1) and you can access it.
You should study "function scope" and "module pattern" in more detail.
You're defining a variable in your functions scope. Instead, you should assign a variable to your current object (this) and of course return that object instead of an empty one.
var myObject1 = function() {
this.x = 0;
return this;
}();

Create instances of a variable in Javascript and access variable within an anonymous function

I have the following JavaScript code:
var objSample = {
variable: 10,
func1 : function(){
someJQueryPlugin(1, function(){
this.variable; // this doesn't work, don't have access
});
}
}
I have two questions:
1) How can I create an instance of the variable so I can have two stand alone objects, each one with its own unique variable values?
Example:
var obj1 = new objSample();
obj1.variable = 1;
var obj2 = new objSample();
obj2.variable = 2;
2) How can I have access to the variable inside an anonymous function from a jQuery plugin inside a function in the object. passing this didn't help.
var objSample = function(){
this.variable = 10
this.func1 = function(){
someJQueryPlugin(1, function(){
this.variable; <-- this doesn't work, don't have access
});
}
}
also you can extend constructor with params
var objSample = function(options){
this.variable = options.val
this.func1 = function(){
someJQueryPlugin(1, function(){
this.variable; <-- this doesn't work, don't have access
});
}
}
var obj1 = new objSample ({val:1})
var obj2 = new objSample ({val:2})
and to access this from callbacks in different context, enclose this to some variable.
So final code looks like:
var objSample = function(options){
var self = this;
self.variable = options.val
self.func1 = function(){
someJQueryPlugin(1, function(){
self.variable;
});
}
}
You need to change the code from an object literal to a constructor function and ensure that you reference the right this in the func1 function.
function ObjSample() {
this.variable = 10;
this.func1 = function () {
var _this = this;
someJQueryPlugin(1, function () {
_this.variable;
});
}
}
DEMO

Javascript callbacks and "this" [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I have the following Javascript code, and I'm trying to get a callback to work as shown below. I want to see an alert with "123" in it.
var A = function(arg){
this.storedArg = arg;
this.callback = function(){ alert(this.storedArg); }
}
var B = function() {
this.doCallback = function(callback){ callback(); }
}
var pubCallback = function(){ alert('Public callback') };
var a = new A(123);
var b = new B();
b.doCallback(pubCallback); // works as expected
b.doCallback(a.callback); // want 123, get undefined
I understand what is happening but I'm not sure how to fix it. How can I get a callback function that references my a object? In my case, I can make changes to A but not B.
So what you want is to pass the context to the doCallBack.
E.g.
doCallBack = function (callback, callee) {
callback.apply(callee);
}
So then you would do:
b.doCallBack(a.callback, a);
If you cannot modify the B then you can use closure inside A:
var A = function (arg) {
var self = this;
this.storedArg = arg;
this.callback = function () { alert(self.storedArg); }
}
You can create a variable that holds the wanted scope for this by putting it into variable that
var A = function(arg){
this.storedArg = arg;
var that = this; // Add this!
this.callback = function(){ alert(that.storedArg); }
}
Working demo here: http://jsfiddle.net/vdM5t/
I understand what is happening (during the 2nd callback, "this" is b and not a)
No, JS is no class-based language where something could happen. If function(){ alert(this.storedArg); is just called as callback(); (like in b.doCallback), the this keyword points to the global object (window).
To get around that, you'd have to change A to
var A = function(arg){
var that = this; // store reference to the current A object
this.storedArg = arg;
this.callback = function(){
alert(that.storedArg); // and use that reference now instead of "this"
};
}
If you don't expect the storedArg property to change, you could even make it more simple:
var A = function(arg){
this.storedArg = arg;
this.callback = function(){
alert(arg); // just use the argument of the A function,
// which is still in the variable scope
};
}
You need to pass the context you want the callback to execute in:
var B = function() {
this.doCallback = function(callback, context) {
callback.apply(context);
};
};
b.doCallback(a.callback, a); // 123
http://jsfiddle.net/a9N66/
Because inside A.callback function, this does not refer to A but to window object.
var A = function(arg){
this.storedArg = arg;
this.callback = function(){ alert(this.storedArg); }
-----------------------------------^-----------------
}
You can try this,
var A = function(arg){
this.storedArg = arg;
var that = this;
this.callback = function(){ alert(that.storedArg); }
}
var B = function() {
this.doCallback = function(callback){ callback(); }
}
var pubCallback = function(){ alert('Public callback') };
var a = new A(123);
var b = new B();
b.doCallback(pubCallback); // works as expected
b.doCallback(a.callback); // alerts 123
When you do this:
b.doCallback(a.callback);
that just calls a's callback function without telling it to use a for this; so the global object is used for this.
One solution is to wrap that callback up:
b.doCallback(function() { a.callback(); });
Other solutions include binding the callback to a, using jQuery.proxy() (which is just a fancy way of doing my first solution), or passing in a to doCallback and invoking callback on a using apply.

Calling method inside another method in javascript?

I am having a JavaScript namespace say
A={
CA: function() {
this.B();
},
B: function() {
var test='test';
var result='t1';
C: function() {
this.test='test1';
.....
.....
return 'test1';
}
result=this.C();
return result;
}
}
Now when I am executing such code it is giving that TypeError: this.C is not a function. Can somebody tell me why it is so. I know it is something related with lexical scoping but am unable to understand this.
You have to be careful when you use this to identify anything in Javascript because each time you change scope "this" changes.
Assigning the 'this' reference to it's own variable helps get around this.
var a = new function() {
var self = this;
self.method = function() { alert('hiya'); };
var b = function() {
this.method(); // this isn't 'a' anymore?
self.method(); // but 'self' is still referring to 'a'
};
};
I think the problem is that when this.C() is executed inside the function referred to by B, this refers to the object that contains B, that is, object A. (This assumes B() is called within the context of A)
The problem is, C does not exist on the object A, since it's defined within B. If you want to call a local function C() within B, just use C().
EDIT:
Also, I'm not sure what you've posted is valid JavaScript. Specifically, B should be defined this way, since you can't use the object:property syntax within a function.
B: function()
{
var test='test';
var result='t1';
var C = function()
{
this.test='test1';
return 'test1';
}
result=C();
return result;
}
I am actually surprised that your code doesn't give you error on the 'C:' line.
Anyway, your syntax to define a function is not correct. Define it using the var keyword. Also, notice that I created the 'closure' so that the function C can access 'this'. See the code below:
A={
CA: function()
{
this.B();
},
B: function()
{
var test='test';
var result='t1';
var self = this;
var C = function()
{
self.test='test1';
.....
.....
return 'test1';
}
result=C();
return result;
}
}
If you want to assign C to 'this' object, you can also do:
A={
CA: function()
{
this.B();
},
B: function()
{
var test='test';
var result='t1';
var self = this;
this.C = function()
{
self.test='test1';
.....
.....
return 'test1';
};
result= this.C();
return result;
}
}
Solution for calling methods from another method. (Essentially the pointer "this" must be assigned to a variable and the new variable used in place of this.)
function myfunction(){
var me = this;
me.method1 = function(msg){ alert(msg); }
me.method2 = function(){
me.method1("method1 called from method2");
}
}
var f as new myfunction();
f.method2();
This example shows how one can call a method from within another method or from outside using an instance of the function.

Categories