Result of expression 'xxxx' is not a constructor in JS - javascript

Trying to create an object in Javascript (for Appcelerator/Titanium).
The "object" is defined like this:
function server () {
this.cacheimages = 0;
this.login = "";
this.name = "";
this.root = "";
this.signup = "";
this.useimages = 0;
this.userexists = "";
this.isdefault = 0;
return this;
}
In the same file, in another function when I run this line: var server = new server(); I get the error Result of expression 'server' is not a constructor.
I have tried it with and without the "return" line, neither work. What am I doing wrong?

What happens if you change the name of the variable?
var server2 = new server();

Functions are 'first class citizens' in javascript, meaning they are variables (or better still: objects, like everything in javascript is an object). So your constructor function could also be written as
var server = function() {
//[...]
}
Now, if you declare a new variable called server, this overwrites the constructor function, being a variable too.
It's common practice to upcase the name of constructor functions. If you use function Server() { ... }, var server = new Server (no need for parenthesis by the way) you're fine.

Related

Typescript compiled code using nested and immediate invoke function

I am trying to understand that why the following:
I have
class User {
wow:String = "xxx";
}
and TypeScript compiler compiles it to
var User = (function () {
function User() {
this.wow = "xxx";
}
return User;
}());
rather than
var User = function() {
this.wow = "xxx";
};
What are the advantages of using the nested User constructor and immediate function invocation?
There may be several good reasons, but I suspect one of them is that if you execute the following plain old JavaScript (over TypeScript's compiler output) :
var john = new User();
console.log("John constructed with: " + john.constructor);
you then get,
John constructed with: function User() {
this.wow = "xxx";
}
instead of,
John constructed with: function() {
this.wow = "xxx";
}
where the chance to see that "User" (the constructor function's identifier) may give a helpful hint, while debugging something later on, or etc.
'HTH,

node.js instantiate class multiple times

I have a class file that creates socket connections based on the parameter passed in during instantiate.
When I try to instantiate this file multiple times (for loop) it looks like the node.js is handling it like singleton.
Is there a way I can create new instances from a same js file that can hold its own arguments passed?
app.js
for(var i....){
require('./controller/sockets')(param[i]);
}
./controller/sockets
var util = require('util');
var param
Socket = function(iParam) {
param = iParam;
};
util.inherits(Socket,EventEmitter);
Socket.prototype.test = function(){
return param;
};
module.exports = Socket;
Thank you!
Your constructor doesn't actually create anything. All it does it store an argument in a variable. So, when you call it N times, that's all it does is store a different value into the same variable N times in a row.
Your code is essentially doing this:
var param;
var Socket = function(iParam) {
param = iParam;
}
for(var i....){
Socket(param[i]);
}
It is not clear to me what you want it to do, but perhaps the constructor needs to create an object (probably using new), initialize it and then return it.
If you want a new Socket object back from each call to the constructor, then you can do it like this:
var util = require('util');
function Socket(iParam) {
this.param = iParam;
}
util.inherits(Socket,EventEmitter);
Socket.prototype.test = function(){
return this.param;
};
module.exports = function(x) {
return new Socket(x);
};

Making JavaScript private methods accessible to its public methods

I understand there are couple of patterns to make JavaScript 'class-like'.
I would like to take the 'extending by prototype' way... simply because it looks more neat. I am not worried about performance much here...
In the below example I have a class (basically function) MetricsChart. I have couple of public methods and one private method (basically a reusable method).
Here from the public method (drawOrAdd) I can't access the private method (_convertArrayToTable), how can I do that?
function MetricsChart(containerId, chartType) {
this._container = document.getElementById(containerId);
this._chartType = chartType;
this._isChartDrawn = false;
this._chartData = null;
var _convertArrayToTable = function (data) {
return google.visualization.arrayToDataTable(data);
}
}
MetricsChart.prototype.drawOrAdd = function(data)
{
if (!this.isChartDrawn()) {
var chart = new google.visualization.LineChart(this._container);
if (chart) {
var table = _convertArrayToTable(data);
console.log(table);
this._isChartDrawn = true;
}
}
}
MetricsChart.prototype.isChartDrawn = function () {
return this._isChartDrawn;
}
MetricsChart.prototype.getChartData = function () {
}
One way I accidentally found was to enclose the public methods inside the MetricsChart class itself...
It works for me :): I can access the public methods outside and the public method can access the private method (serves the purpose).
Below code... Is this right? Am I doing anything wrong?
function MetricsChart(containerId, chartType) {
this._container = document.getElementById(containerId);
this._chartType = chartType;
this._isChartDrawn = false;
this._chartData = null;
var _convertArrayToTable = function (data) {
return google.visualization.arrayToDataTable(data);
}
MetricsChart.prototype.drawOrAdd = function (data) {
if (!this.isChartDrawn()) {
var chart = new google.visualization.LineChart(this._container);
if (chart) {
var table = _convertArrayToTable(data);
console.log(table);
this._isChartDrawn = true;
}
}
}
MetricsChart.prototype.isChartDrawn = function () {
return this._isChartDrawn;
}
MetricsChart.prototype.getChartData = function () {
}
}
So, here a couple of things, in order to understand what you have done precisely.
First of all:
function foo() {
var i = 0;
function bar() {
return true;
}
}
What's happening here: every time the function foo is called, it creates in its scope a new variable i, and a new function bar. The function bar and the variable i are in its scope, it means they're local: there is no way, with this code, to access to either i or bar outside the function foo. Also because, once the function foo is terminated, both i and bar are disposed.
So, this is why you cannot access from your "public" method to the "private" one, and I hope it's more clear now. The only way for a function to access to a function or variable is that there is a reference shared in the same scope. So, this is what you have done in your last example: you define your "public" methods in the same scope where you define your "private" method. In this way they can access each other. However, the way you have done, has a big downside. As I said previously, the function bar is created every time the function foo is called. In a "class" example, it means:
function MyClass() {
function myprivate() {}
MyClass.prototype.mypublic = function () { return myprivate() }
}
It means that every time you're creating an instance of MyClass, you're creating two new functions, and you're rewrite all the time the prototype of your "class". This is far from be a good approach. In fact, if you have something like:
var a = new MyClass();
var _mypublic = a.mypublic;
var b = new MyClass();
console.log(_mypublic === b.mypublic) // false
console.log(_mypublic === a.mypublic) // false too!
So, you guess right but you executed wrong. What you need here is a the "module pattern": nowadays you can use CommonJS module in nodejs or AMD in browser and so on, but the basic idea is defined a "scope" and exports from this scope only what you want. In your case, you could have:
// this is your "module"
;(function(exports) {
// your local (private) function
var _convertArrayToTable = function (data) {
return google.visualization.arrayToDataTable(data);
}
function MetricsChart(containerId, chartType) {
this._container = document.getElementById(containerId);
this._chartType = chartType;
this._isChartDrawn = false;
this._chartData = null;
}
MetricsChart.prototype.drawOrAdd = function(data) {
if (!this.isChartDrawn()) {
var chart = new google.visualization.LineChart(this._container);
if (chart) {
var table = _convertArrayToTable(data);
console.log(table);
this._isChartDrawn = true;
}
}
}
// you decided to exports to the main scope what you want
exports.MetricsChart = MetricsChart;
}(this)); // here `this` is the global object
And that's it. You have created a closure, using the "module pattern", and from the "public" method you can access to the "private" function, because they're defined in the same scope. But because you do not do that in the "class" constructor, you don't redefine them every time you instantiate a new object. Therefore, the previous example written in this way, will give the right result:
var a = new MyClass();
var _mypublic = a.mypublic;
var b = new MyClass();
console.log(_mypublic === b.mypublic) // true
console.log(_mypublic === a.mypublic) // true
What you've done isn't necessarily "wrong"...it just looks weird. Also, you won't be able to access "MetricsChart.prototype.*" until after you've created an instance of "MetricsChart". Depending on how you are using this object, it may not matter.
That being said, another way is to keep your original structure, but move the following outside of the constructor:
var _convertArrayToTable = function (data) {
return google.visualization.arrayToDataTable(data);
}
It would still be private to your module which should be good enough (you are using modules right?).
What you have done works perfectly.
You can't inherit private methods in any OOP language in terms of overriding them or accessing them directly. They are private. So it makes no sense to have them prototyped for inheritance purposes. You have wrapped them in function scope so they are as "private" as they need to be.
To access the private methods use privilege methods. Check this document: http://javascript.crockford.com/private.html.
About your code check this answer:
Setting javascript prototype function within object class declaration
p.s.
function Test()
{
var p = function(pv)
{
//
}
this.e = function (ap) { p(ap) }
}
var n = new Test();
n.e("e"); // It is legal call
n.p(); // will throw
But if you declare a private function in c-tor it will be executed on first creation of object of this type. When declare a methods in prototype this methods are add before any code execution. In general the browser first check the js file to collect all methods for prototype and than execute any code. So when you declare a prototype methods into c-tor this methods will be available only after first creation of the object of those type. ( Sorry for my English ).
Check this situation:
function Test()
{
alert(this.ST_A);//alert undefined
alert(this.ST_B);//alert 2
Test.prototype.ST_A = 1;
alert( this.ST_A)//alert 1
}
Test.prototype.ST_B = 2;
In first pass the browser will populate Test with ST_B and ST_B will be available anywhere any time. After than in second pass the browser will start to execute the code in this time ST_A will not be visible until the browser execute the Test.prototype.ST_A = 1;

Getting undefined from javascript module property

I have a feeling I'm missing something obvious. I'm returning a variable from my javascript module, but it keeps coming back undefined.
Here's the module:
var MyNs = MyNs || {};
MyNs.Global = function () {
var privateTestVar;
var init = function () {
if (privateTestVar == null ) {
privateTestVar = "this is a test" ;
console.log( 'Init: ' + privateTestVar);
}
};
var Public = {
init: init,
TestVar: privateTestVar
}
return Public;
} ();
Here's the call:
MyNs.Global.init();console.log( 'Called: ' +MyNs.Global.TestVar);
The console.log in the init function works fine and returns the value, but the other console log returns undefined. I'm totally missing it. Any help would be appreciated.
Update: I've change the code a bit, to this:
var privateTestVar = function () { return 'Test!'; }
var Public = {
TestVar: privateTestVar
}
And variations of that, but it returns this exact text to the console: "function () { return 'Test!'; }"
At the time that Public is assigned here:
var Public = {
init: init,
TestVar: privateTestVar
}
privateTestVar is still undefined (because init() hasn't been run yet) so the TestVar property is initialized to the value of privateTestVar which is undefined.
The TestVar property gets assigned the value of privateTestVar. If it's initially undefined (which it is in this case), it will stay that way until you assign something different to the TestVar property. I won't automatically inherit future values of privateTestVar which is perhaps what you were expecting. Javascript does not have a way of specifying that one variable will always contain whatever is assigned to another variable. privateTestVar and the TestVar` property each have their own value. Assigning something to one variable does not affect the other.
I'd suggest making a private variable really a private one, using getters instead. This will work correctly:
var Public = {
init: init,
getVar: function() { return privateTestVar; }
}
MyNs.Global.init();console.log( 'Called: ' +MyNs.Global.getVar());
Issue is as stated by #jfriend00. Change the code to
var init = function () {
if (privateTestVar == null ) {
privateTestVar = "this is a test" ;
Public.TestVar = privateTestVar;
console.log( 'Init: ' + privateTestVar);
}
};
I didn't test this out but theoretically it should work.
I think this is the structure you are looking for:
function PrivateFunc(private, public){
this.privateVar = private;
this.publicVar = public;
}
function PublicFun(public){
this.publicVar = public;
if(this.publicVar == null)this.publicVar = 'This is a public variable.';
this.PrivateFun = function(private){
return new PrivateFunc(private, this.publicVar);
}
}
var pf = new PublicFun('public variable');
var pv = pf.PrivateFun('private variable');
console.log('pf.publicVar = '+pf.publicVar);
console.log('pf.privateVar = '+pf.privateVar);
console.log('pv.publicVar = '+pv.publicVar);
console.log('pv.privateVar = '+pv.privateVar);
Notice that PrivateFunc is not PrivateFun. The real factor comes down to the key word this. this refers to the current Object as when you type this. var is only accessible inside your method. You should think of a JavaScript Object as an Associative Array. If that doesn't suit your needs try:
var jsObject = {
publicVar: null,
PrivateFun: function(private){
var privateVar = private; //cannot access with dot
return this;
},
PublicFun: function(public){
this.publicVar = public;
if(this.publicVar == null)this.publicVar = 'This is a public variable';
return this;
}
}
var pf = jsObject.PublicFun();
var pv = jsObject.PrivateFun('private variable');
console.log('pf.publicVar = '+pf.publicVar);
console.log('pf.privateVar = '+pf.privateVar);
console.log('pv.publicVar = '+pv.publicVar);
console.log('pv.privateVar = '+pv.privateVar+' //cannot access with dot');
Note that Object Literals are not Constructors, so you cannot make new instances. Also, in the Object Literal case, var privateVar is virtually useless, unless you don't want the privateVar returned. this must be returned in order to access jsObject, which holds the reference to publicVar.

Dynamically firing a named-spaced method via JavaScript

I have multiple external JavaScripts that are namespaced based on the section of the site. I am trying to dynamically fire methods, but am unable to get the methods to fire. Can anyone tell me what the problem is?
If I add this, the method fires:
Namespace.Something.init()
But when I try to do it like this, nothing happens (note: namespace equals Namespace.Something and functionname equals init):
namespace[functionname]();
Unless you want to use eval which I am sure you don't the following works.
This assumes that all your methods are the same level deep i.e namespace.somename.somemethod
var Namespace = {
Something: {
init: function() {
console.log('init called');
}
}
};
Namespace.Something.init();
var namespace = "Namespace";
var section = "Something";
var method = "init";
this[namespace][section][method]();
as Namespace is part of the global scope you can access it from this[namespace]
I asked the same question a few weeks ago, though I think I phrased it slightly differently. See this.
Basically, you need to parse the string functionname one piece at a time.
By the way, using the walk_path code from that answer, here's a general purpose function I wrote to run a function from a string including arguments.
// run an arbitrary function from a string. Will attempt to parse the args from parenthesis, if none found, will
// use additional arguments passed to this function.
utils.runFunction = function (funcdef) {
var argPos = funcdef.indexOf('(');
var endArgPos = -1;
var args = undefined;
var func = funcdef;
if (argPos > 0) {
endArgPos = funcdef.indexOf(')', argPos);
if (endArgPos > 0) {
args = funcdef.substring(argPos + 1, endArgPos).split(',');
func = funcdef.substring(0, argPos - 1);
}
} else {
args = Array.prototype.slice.call(arguments, 1);
}
var func = walk_path(window, func);
return !args ? func() : func.apply(null, args);
};
var methodName = 'Namespace.Something.init';
var methodParts = methodName.split('.');
var method = this;
for (var i=0; i < methodParts.length; i++) {
method = method[methodParts[i]];
};
method(the arguments you want);

Categories

Resources