Passing javascript object property - javascript

How do you go about passing an objects properties in the follwoing situation:
ObjectTest = function()
{
this.var1= "3";
this.var2= "";
}
and the call
ObjectTest .prototype.allFriends = function() {
function bindEvents() {
//pass var1 here
}
}
Is there a way to pass the ObjectTest properties without passing them as properties of the bindEvents(). I'd prefer a global solution if at all possible

You use the same code in the prototype of allFriends as you used in the constructor:
ObjectTest = function()
{
this.var1= "3";
this.var2= "";
}
ObjectTest.prototype.allFriends = function() {
alert(this.var1);
}

It's the same: this.var1 - run this:
ObjectTest = function() {
this.var1 = 3;
this.var2 = "";
};
ObjectTest.prototype.allFriends = function() {
alert(this.var1);
};
x = new ObjectTest();
x.allFriends();
Or see this fiddle: http://jsfiddle.net/9XYZU/

ObjectTest.prototype.allFriends = function() {
do_smth_with(this.var1);
}
Beware, though, that you create a new ObjectTest by calling new ObjectTest(); without the new keyword it will not work.
EDIT: It will still work, because of the inner function will inherit the outer function's (allFriends) scope:
ObjectTest .prototype.allFriends = function() {
function bindEvents() {
console.log(this.var1);
}
}
If it still doesn't work for you, use a reference to the parent's this:
ObjectTest .prototype.allFriends = function() {
var parent = this;
function bindEvents() {
console.log(parent.var1);
}
}

Related

Triple nested object functions js

I have an object mainly composed of functions/ methods, much like this (Which should work!):
function thing1(){
this.thing2 = function(){
this.thing3 = function(){
alert();
}
}
}
But
When I call thing1.thing2.thing3(), I get
Cannot read property 'thing3' of undefined
complete pseudocode:
function thing1(){
this.thing2 = function(){
this.thing3 = function(){
alert();
}
}
}
var foo = new thing1();
foo.thing2.thing3();
thing2 doesn't return anything which results in returning undefined.
If you want to write chained functions, you need to return this:
function thing1() {
this.thing2 = function() {
this.thing3 = function() {
alert();
}
return this; // chained
}
}
Generally speaking, it's better to assign methods to a functions prototype if you intend to use it as a constructor. You can still chain functions on the prototype.
function thing1() {
}
thing1.prototype.thing2 = function() {
return this; // chained
};
thing1.prototype.thing3 = function() {
alert('thing3');
return this; // you can make this one chained as well, if you like
};
var t = new thing1();
t.thing2().thing3().thing2().thing3();
If you want to just create a basic chain without requiring parentheses, you could create a separate getter function.
function thing1() {
}
Object.defineProperty(thing1.prototype, 'thing2', {
get: function() {
return this;
}
});
thing1.prototype.thing3 = function() {
alert('thing3');
return this;
};
var foo = new thing1();
foo.thing2.thing3().thing2.thing3();
Those are constructors:
function thing1(){
this.thing2 = function(){
this.thing3 = function(){
alert();
}
}
}
(new (new thing1()).thing2()).thing3()
If you want to call thing1.thing2.thing3() you should format it like this:
function thing1(){
this.thing2 = {
thing3: function(){
alert();
}
}
}
var foo = new thing1();
foo.thing2.thing3()

Javascript inheritance method overriding doesn't work

I have trouble understanding how the method overriding works in Javascript.
In the code below, I have CustomFieldTable class subclassing from Table class, and it both have createList function.
How can I override the createList function from the below code so that createList function from the CustomFieldTable class can be run from the reload function?
Current console output:
'Should be silent overridden createList Function'
Desired console output:
'Custom Field create list'
'obj1'
'obj2'
'obj3'
$(document).ready(function() {
var table = new CustomFieldTable();
table.init();
});
function Table() {
var self = this;
self.table_data = [];
self.reload = function() {
self.table_data = ["obj1", "obj2", "obj3"];
self.createList();
}
self.createList = function() {
alert("Should be silent overridden createList Function");
}
}
CustomFieldTable.prototype = new Table();
CustomFieldTable.prototype.constructor = CustomFieldTable;
function CustomFieldTable() {
var self = this;
self.init = function() {
self.reload();
}
self.createList = function() {
alert("Custom Field create list");
for (var i = 0; i < self.table_data.length; i++) {
alert(self.table_data[i]);
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can restructure this this way:
function myClass() {
// Constructor function
this.myProp = "This is myProp on myClass";
}
myClass.prototype.firstMethod = function() {
document.write("I am firstMethod on myClass<br\>");
}
myClass.prototype.secondMethod = function() {
document.write("I am to be overwritten<br\>");
}
function myExtendedClass() {
// This calls "super" class constructor with the correct "this"
myClass.call(this);
this.myOtherProp = "This is a prop only on my extended class<br\>";
}
// Set with super class prototype and set proper constructor
myExtendedClass.prototype = Object.create(myClass.prototype);
myExtendedClass.prototype.contructor = myExtendedClass;
// Overwrite or set new methods on extended class object
myExtendedClass.prototype.secondMethod = function() {
document.write("I overwrote my super's method<br\>");
}
var a = new myExtendedClass();
console.log(a);
a.firstMethod();
a.secondMethod();
To be exact... a correction of your code would be:
$(document).ready(function() {
var table = new CustomFieldTable();
table.init();
});
function Table() {
this.table_data = [];
}
Table.prototype.reload = function() {
this.table_data = ["obj1", "obj2", "obj3"];
this.createList();
}
Table.prototype.createList = function() {
alert("Should be silent overridden createList Function");
}
function CustomFieldTable() {
Table.call(this);
}
CustomFieldTable.prototype = Object.create(Table.prototype);
CustomFieldTable.prototype.constructor = CustomFieldTable;
CustomFieldTable.prototype.init = function() {
this.reload();
}
CustomFieldTable.prototype.createList = function() {
alert("Custom Field create list");
for (var i = 0; i < this.table_data.length; i++) {
alert(this.table_data[i]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A few things to note, when you set these functions inside the constructor you are creating new instances of the function object whenever you create an object. Instead, use the .prototype to set methods on the object. Then use Object.create to extend the prototype and call the super from the constructor.

JQuery function is not defined

this.slideUpComm = function (){
$("#Day-events-content p").addClass("hidden").slideUp("fast");
}
this.showhideEvents = function() {
$("#Day-events-content").on("click", ".eventsToggle", function() {
var obj = $(this).next();
if ($(obj).hasClass("hidden")) {
slideUpComm();
$(obj).removeClass("hidden").slideDown();
} else {
$(obj).addClass("hidden").slideUp();
}
});
}
I would like to use slideUpComm as function that I include on different events but console return Uncaught ReferenceError: slideUpComm is not defined.
How I should pass function to function ? Should I use callback?
function dateObj() {
this.d = new Date();
this.day = this.d.getDate();
this.numDay = this.d.getDay();
this.month = parseInt(this.d.getMonth());
this.year = this.d.getFullYear();
this.slideUpComm = function (){
}
this.showhideEvents = function() {
});
}
}
My Object look like above.
The problem is slideUpComm is a member of an object... so you need to use the object reference to invoke the method
//create a closure varaible to hold the reference to the instance
var self = this;
this.slideUpComm = function (){
$("#Day-events-content p").addClass("hidden").slideUp("fast");
}
this.showhideEvents = function() {
$("#Day-events-content").on("click", ".eventsToggle", function() {
var obj = $(this).next();
if ($(obj).hasClass("hidden")) {
//slideUpComm is a instance property so access it using the instance
self.slideUpComm();
$(obj).removeClass("hidden").slideDown();
} else {
$(obj).addClass("hidden").slideUp();
}
});
}
slideUpComm is a function of dateObj, you can not directly invoke the function. So to invoke a function you need to create an instance of function/object
var a = new dataObj();
then you can invoke the function using
a.slideUpComm()
Could this not be reduced to:
$("<object>").slideToggle();
?

Using "dot" inside a prototype name in JavaScript

Lets say I have this class:
function classA(n){
this.name = n
}
classA.prototype.getName = function(){
return this.name
}
var x = new classA('john')
console.log(x.getName())
My question is: can I group multiple methods inside a namespace? So I would like to do that:
var x = new classA('john')
console.log(x.CONSTANT.getName())
So I would like to call some methods as x.someMethod() and others as x.CONSTANT.otherMethod()
PS: I'm looking for a cross-browser method. Bind is not working in Safari and IE9.
You can do it, for example, via bind. Google es5 shim for implementation of bind in browsers, which don't support it natively.
function MyClass(name) {
this.name = name;
this.CONSTANT.otherMethod = this.CONSTANT.otherMethod.bind(this);
}
MyClass.prototype.CONSTANT = {
otherMethod: function() {
alert(this.name);
}
};
As far as I know a constant is just a property and it can't contain methods, you need to separate your objects and use methods to have the same effect:
function A (id) {
this.id = id;
this.showId = function () { return this.id; }
};
function B (a) {
this.a = a;
this.getA = function () { return this.a; }
}
var a = new A(12);
var b = new B(a);
b.getA().showId();
edit:
You can use a literal object as follow
function B (id) {
this.id = id;
this.CONSTANT = { otherMethod: function () { alert("..."); } };
someMethod = function () { return this.id; }
}
but the literal CONSTANT object can't access B-object methods,
Consider the #kirilloid post to round this.
You can, but you have to be careful because it won't act like you think it will. The this for the method will be the namespace, not the root object.
For example, in x.CONSTANT.getName(), the this object will be x.CONSTANT, and not x.
Here's some sample code which kinda does what you ask (or in jsfiddle):
function MyClass() {}
MyClass.prototype.CONSTANT = {
getName: function() {
alert('Foo');
}
};
var c = new MyClass();
c.CONSTANT.getName();
To make sure the this is right, you need to do much more.
You can use getters/setters (read this article) to achieve this. For example you may define it like this:
classA.prototype.__defineGetter__('CONSTANT', function() {
var that = this;
return {
getName: function() {
return that.name;
}
};
});
Note that holding reference to the object. It will work now
x = new classA('test');
x.CONSTANT.getName();
// result - test

OO Javascript Question

Given the following:
var someObject = {};
someObject.prototype.a = function() {
};
someObject.prototype.b = function() {
//How can I call someObject.a in this function?
};
How can I call someObject.a from someObject.b? Thanks.
This will work:
someObject.prototype.b = function() {
this.a();
};
However your definition of someObject is slightly wrong, it should be:
var someObject = function() {};
Test script:
var someObject = function() {};
someObject.prototype.a = function() {
alert("Called a()");
};
someObject.prototype.b = function() {
this.a();
};
var obj = new someObject();
obj.b();
I think you probably meant to do this:
function Thingy() {
}
Thingy.prototype.a = function() {
};
Thingy.prototype.b = function() {
this.a();
};
var someObject = new Thingy();
It's constructor functions, not plain objects, that have a special prototype property. The prototype of a constructor function is assigned to all objects created with that constructor via the new keyword as their underlying prototype, which gives them default properties (which may reference functions, as they do above).

Categories