In the BusMonitor object, "this" refers to window object thats why "name" property become global for entire script when I call BaseFunction.call(this) on BusMonitor object. I just want the BaseFunction's properties only available to BusMonitor object. How to do that ?
function BaseFunction() {
this.name = "test";
}
var BusMonitor = function () {
BaseFunction.call(this);
return {
init: function () {
}
}
}();
I can do it by the way below but I dont want to create object like this.
function BusMonitor () {
BaseFunction.call(this);
return {
init: function () {
}
}
};
var busMonitor = new BusMonitor();
busMonitor.init();
You can, if it's possible of course, create object first and then pass it to BaseFunction
function BaseFunction() {
this.name = "test";
}
var BusMonitor = function () {
var obj = {
init: function () { }
};
BaseFunction.call(obj);
return obj;
}();
You can define a localScope in BusMonitor to hold name value, like this:
function BaseFunction() {
this.name = "test";
}
var BusMonitor = function () {
var localScope = {};
BaseFunction.call(localScope);
console.log("local name:" + localScope.name);
return {
init: function () {
}
}
}();
console.log("global name: " + name);
Related
I want to make a static array in a javascript class, for this I do:
var Manager = (function () {
function Manager() {
var ubications = new ArrayList();
this.ubicationsArray = function () {
return(ubication);
};
}
Manager.prototype.addUbication = function (ubication) {
Manager.ubicationsArray().add(ubication);
};
Manager.prototype.getUbication = function (index) {
return Manager.ubicationsArray().get(index);
};
Manager.prototype.sizeOfUbications = function () {
return Manager.ubicationsArray().size();
};
return Manager;
}());
Manager["__class"] = "Manager";
Where ubications is the static array and the function ubicationsArray is the public function to acces the array.
I try to use this code with:
var ubication = new Ubication(123,456);
var manager = new Manager();
manager.addUbication(ubication);
alert(manager.sizeOfUbications());
But I got this error:
Uncaught TypeError: Manager.ubicationsArray is not a function
How is the correct way to use static arrays in a javascript code?
Currently, JavaScript can only do privacy with respect to function scope.
function Manager () {
}
Manager.prototype = (function (){
var ubications = [];
return {
addUbication: function (u) {
ubications.push(u);
},
getUbication: function (index) {
return ubications[index];
},
sizeOfUbications: function () {
return ubications.length;
}
};
})();
Inside your constructor function, this.ubicationsArray assigns a property to the instance of the object, not the constructor itself.
Perhaps you want something like this:
function Manager() {
}
var ubications = new ArrayList();
Manager.ubicationsArray = function () {
return(ubication);
};
Note that this property isn't really "private". This would be more-private:
var Manager = (function () {
function Manager() {
}
var ubications = new ArrayList();
Manager.prototype.addUbication = function (ubication) {
ubications.add(ubication);
};
Manager.prototype.getUbication = function (index) {
return ubications.get(index);
};
Manager.prototype.sizeOfUbications = function () {
return ubications.size();
};
return Manager;
}());
Manager["__class"] = "Manager";
I've got two object prototypes like this:
function Tag(name, description) {
this.name = name;
this.description = description || null;
}
function Category(name, description) {
this.name = name;
this.description = description || null;
}
Both of them are exactly the same, which seems awkward. Is it possible to merge them both into an object named 'Entity', and refer to them both by different names (the original 'Tag' and 'Category')?
This may be further complicated by the fact I need to refer to the current prototype name inside the prototype.
Tag.prototype.toJSON = function() {
return {
__type: 'Tag',
name: this.name,
description: this.description
};
};
How can I apply the same 'toJSON' extension to the 'Entity' object, but make sure it returns 'Tag' or 'Category' in the '__type' field, dependent on which object is being used?
I would do something like this:
Dummy = function () {};
Entity = function (name) {
this.name = name;
};
Entity.prototype.toString = function () {
return "My name is " + this.name + ".";
};
A = function () {
Entity.call(this, 'A');
};
Dummy.prototype = Entity.prototype;
Dummy.prototype.constructor = A;
A.prototype = new Dummy();
B = function () {
Entity.call(this, 'B');
};
Dummy.prototype = Entity.prototype;
Dummy.prototype.constructor = B;
B.prototype = new Dummy();
document.body.innerHTML = ""
+ (new A()) + "<br />"
+ (new B());
Here is a small function to make things cleaner (hopefully):
function Nothing () {};
function extend (Sup, proto) {
function Class () {
if (this.init) {
this.init.apply(this, arguments);
}
}
Nothing.prototype = Sup.prototype;
Nothing.prototype.constructor = Sup;
Class.prototype = new Nothing();
delete Nothing.prototype;
for (var k in proto) {
Class.prototype[k] = proto[k];
}
return Class;
}
Here is how to use it:
Entity = extend(Nothing, {
init: function (name) {
this.name = name;
},
toString: function () {
return "My name is " + this.name + ".";
}
});
A = extend(Entity, {
init: function () {
var sup = Entity.prototype;
sup.init.call(this, 'A');
}
});
B = extend(Entity, {
init: function () {
var sup = Entity.prototype;
sup.init.call(this, 'B');
}
});
I'm trying to make private functions in Javascript. Here is my code:
function Person() {
this.id = 5;
};
Person.prototype = {
getId: function() {
return this.id;
},
walk: function() {
alert("i am private");
},
eat: function() {
alert("i am public");
}
};
I want to make walk function private one and eat function is public .
There is no constructions in JavaScript to define real private methods for class, but you can do so:
var Person = (function () {
var Person = function () {
this.id = 5;
};
var walk = function () {
alert("i am private");
};
Person.prototype = {
constructor: Person,
getId: function (){
return this.id;
},
eat: function () {
alert("i am public");
}
};
return Person;
}());
I have following javascript code
function MyFunc () {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return obj.fName();
};
return {
func: function (obj) {
funcCall(obj);
}
};
}
var lol = new MyFunc();
When lol.func({fName: add}); is passed it should invoke the function private function add or when lol.func({fName: div}); is passed it should invoke the private div function. What i have tried does not work. How can i achieve this.
DEMO
In this case it's better to store your inner function in the object so you can easily access this with variable name. So if you define a function "map"
var methods = {
add: add,
div: div
};
you will be able to call it with methods[obj.fName]();.
Full code:
function MyFunc() {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var methods = {
add: add,
div: div
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return methods[obj.fName]();
};
return {
func: function (obj) {
return funcCall(obj);
}
};
}
var lol = new MyFunc();
console.log( lol.func({fName: 'add'}) );
When you pass lol.func({fName: add}) add is resolved in the scope of evaluating this code, not in the scope of MyFunc. You have to either define it in that scope like:
function MyFunc () {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return obj.fName();
};
return {
add: add,
div: div,
func: function (obj) {
funcCall(obj);
}
};
}
var lol = new MyFunc();
lol.func({fName: lol.add});
Or use eval.
It's easy to make private variables accessed by public methods of a module you're exporting:
var makeAModule = function() {
var _secret = 'Ssh!';
var module = {
tellMeYourSecret: function() {
console.log(_secret);
}
};
return module;
}
// > var m = makeAModule();
// > m.tellMeYourSecret();
// Ssh!
Sometimes I need to define properties with Object.defineProperty that are computed by getters using the value of other private variables. Those have to go on an object, though, so I end up making a private object just to hold them. If I don't store all my private members on that object, it gets confusing to remember which props are on it and which aren't, so I put everything there:
var makeAModule = function() {
var priv = {};
priv._secret = 'Ssh!';
Object.defineProperty(priv, 'secretLength', {
get: function() {
return priv._secret.length;
}
});
var module = {
tellMeYourSecret: function() {
console.log(priv._secret);
},
howLongIsYourSecret: function() {
console.log(priv._secretLength);
}
}
return module;
}
// > var m = makeAModule();
// > m.howLongIsYourSecret();
// 4
Is there any way to define a variable (not attached to an object) whose value is computed through a getter? Something like this:
var makeAModule = function() {
var _secret = 'Ssh!';
Object.defineVariable('_secretLength', {
get: function() {
return _secret.length;
}
})
var module = {
tellMeYourSecret: function() {
console.log(_secret);
},
howLongIsYourSecret: function() {
console.log(_secretLength);
}
}
return module;
}
Not directly.
However, you can set it as a property of window, thus making it a global variable. But using global variables is not recommendable, specially if they are secret.
var makeAModule = function() {
var priv = {};
priv._secret = 'Ssh!';
Object.defineProperty(window, '_secretLength', {
get: function() {
return priv._secret.length;
}
});
return {
tellMeYourSecret: function() {
return _secret;
},
howLongIsYourSecret: function() {
return _secretLength;
}
};
};
document.body.innerHTML =
"Secret length: " + makeAModule().howLongIsYourSecret();
Alternatively, you can define your getters as properties of an object, and use a with statement. Note that the with statement can't be used in strict mode.
var makeAModule = function() {
var priv = {};
priv._secret = 'Ssh!';
Object.defineProperty(priv, '_secretLength', {
get: function() {
return priv._secret.length;
}
});
with(priv) {
return {
tellMeYourSecret: function() {
return _secret;
},
howLongIsYourSecret: function() {
return _secretLength;
}
};
}
};
document.body.innerHTML =
"Secret length: " + makeAModule().howLongIsYourSecret();