Not
f().apply(scope);
only
f.apply(scope);
(No () after f .) You want to use the apply function for the f function, rather than calling the f function and access the apply by its return value.
To pass the arguments received by your function to setScope , add the following:
f.apply(scope, arguments);
arguments is an implicit argument for all functions, which is a pseudo-array of the actual arguments passed to the function at run time. apply takes any array-like thing as its second parameter to indicate the arguments used when invoking the base function.
I would also return the return value:
return f.apply(scope, arguments);
So, setScope becomes:
Function.prototype.setScope = function (scope) { var f = this; return function () { return f.apply(scope, arguments); } }
Living example
Note that the normal name of this function and the name it has in the new ECMAScript5 standard , bind (section 15.3. 4.5; ECMAScript5 bind also allows you to curry arguments that are not executed by this implementation). setScope is a particularly unfortunate name because it does not set the scope, it sets the context.
Having said all this, there is no reason why you need setScope in your Person constructor. You can simply do this:
Person = function () { var self = this; this.Name = "asd"; var _public = new Object(); _public.Name = function (value) { if (value == undefined) { return self.Name; } else { self.Name = value; } }; return _public; };
Real time example
But using bind (aka setScope ) can be useful in places where you do not want a new close over the context in which you do it.
Off topic . The way you specify Person will break certain things that people can expect, for example:
var p = new Person(); alert(p instanceof Person);
... because you are replacing the new object created for you, but returning another object from your constructor (which overrides the default value).
Instead of creating a new object and returning it to your constructor, allow the object constructed for you by new as an object (and therefore the Person relation is supported), but you can still get really private variables and use accessors:
function Person() { // Private variable var name = "asd"; // Accessor function this.Name = function(value) { if (typeof value === "undefined") { return name; } name = value; }; }
Living example
As you can see, it is much simpler and it keeps instanceof communication. Please note that we do not qualify our references to name inside name at all, and therefore we use a local variable in a constructor call in which our name function was closed, which is closed above it.
I also took the liberty of giving the constructor function a name, because I am not a fan of anonymous functions . I should have indicated the accessory and name:
function Person() { // Private variable var name = "asd"; // Accessor function this.Name = Person_Name; function Person_Name(value) { if (typeof value === "undefined") { return name; } name = value; } }
Off-topic 2 : the overwhelming convention in JavaScript code is to use the initial caps for function names only for constructor functions (e.g. Person ), and not for other kinds of functions (e.g. name ). Of course, you can do whatever you want, but I thought I was mentioning the convention as it makes it easier for other people to read your code.
It is worth noting: All of these methods lead to the fact that each individual Person object has its own copy of the accessor function. If there are many such objects, this could be a memory problem. If only a little, then good.