Reputation: 263
How can I pass the variable param to the function? My example doesn't work. The 'run' function throws an error = 'param is not defined'
var newClass = function (obj) {
var param = "the param";
var f = function (param) { };
f.prototype = obj;
return nf = new f(param);
};
var Runner = {
run: function () {
console.log("calling method run " + param);
}
};
var nf = newClass(Runner);
nf.run();
Upvotes: 0
Views: 104
Reputation: 1075735
It looks like your goal is for newClass
to return an object that uses Runner
as its prototype and has param
as a property. There's a dramatically simpler way to do that; see comments:
var newClass = function(obj) {
// Create an object using `obj` as its prototype
var nf = Object.create(obj);
// Give it a `param` property
nf.param = "the param";
// Return it
return nf;
};
var Runner = {
run: function() {
// Note the use of `this `on the next line, to access
// the property in the instance
console.log("calling method run " + this.param);
}
};
var nf = newClass(Runner);
nf.run();
Object.create
was added in ES5 (in 2009) and so exists in just about any JavaScript engine that's vaguely recent (so, not the one in IE8); the one-argument version of it above can be shimmed with code very similar to that in your question, see MDN.
On a fully ES5-compliant JavaScript engine, you can use the second argument of Object.create
(which cannot be shimmed/polyfilled) to control the enumerability, writability, and configurability of the property:
var newClass = function(obj) {
// Create and return an object using `obj` as its prototype,
// with a `param` property:
return Object.create(obj, {
param: {
value: "the param"
}
});
};
In that example, param
will be non-enumerable, read-only, and not configurable.
Side note: I wouldn't call a function that creates new objects newClass
, just FWIW. :-)
In a comment you've said:
My goal is to generate a private variable, only accessible from the inside of Runner. In your example, param is accessible from the outside.
If so, you can't do it with Runner
being defined outside the newClass
function because, by definition, that's...outside the newClass
function.
What you can do is define run
within newClass
, perhaps having it turn around and call a function on Runner
that accepts the param as an argument:
var newClass = function(obj) {
// The private variable
var param = "the param";
// Create an object using `obj` as its prototype
var nf = Object.create(obj);
// Create `run`
nf.run = function() {
this.runWithParam(param)
};
// Return it
return nf;
};
var Runner = {
runWithParam: function(param) {
console.log("calling method runWithParam " + param);
}
};
var nf = newClass(Runner);
nf.run();
...or possibly don't use Runner
as the prototype at all:
var newClass = function(runner) {
// The private variable
var param = "the param";
// Create an object with `run` on it
var nf = {
run: function() {
return runner.runWithParam(param);
}
};
// Return it
return nf;
};
var Runner = {
runWithParam: function(param) {
console.log("calling method runWithParam " + param);
}
};
var nf = newClass(Runner);
nf.run();
Upvotes: 3
Reputation: 26201
You can alsways use a constructor as you have originally intended but if you want to access param
from the instantiated objects, then it has to be a property of either the instantiated object or the constructor's prototype. I choose to put it inside the constructor's prototype (i mean to the obj
object provided through as an argument, which is later assigned as the constructor function F's prototype).
And of course in order to have access to the properties through object methods we have to refer them with a designation of which parent the method is invoked from. Which is this
.
var newClass = function (obj) {
var F = function () { };
obj.param = "the param";
F.prototype = obj;
return new F();
};
var Runner = { run: function () {
console.log("calling method run " + this.param);
}
};
var nf = newClass(Runner);
nf.run();
Upvotes: 0