I declared the function:
function makePerson() {
this.first = 'John';
this.last = 'Oliver';
fullName = function(){
return this.first + this.last;
}
}
Did not instantiate it but called this function.
makePerson()
Now I am able to access first, last and fullName in global access.
Can someone explain me why it happens.
Note: Rather than calling, I instantiated it and checked. It is not in global and is accessible within function/class/object scope.
These are the normal semantics of the this keyword in a function. this may be evaluated in several ways, depending on how you call the function. Let's say we have the function f which body contains the this keyword :
In f(a,b) (standard function call syntax) this is bound to the global JavaScript Object, which means that if you add properties to this in the function body, you actually add them to global scope.
In anObject.f(a,b) (method call syntax), this is bound to anObject.
In new f(a,b) (constructor call syntax), this is bound to the object being constructed.
this can be a source of confusion, and as soon as a function body contains this, the function stops being first-class. For that reason, I recommend you to avoid using this as much as you can, as does Douglas Crockford.
If you want to make a factory function (which I strongly recommend for the reason above), you may do it that way :
function makePerson() {
var person = {
first: 'John',
last: 'Oliver'
};
person.fullName = function(){
return person.first + person.last;
};
return person;
}
If you still want to make a constructor, convention dictates that the name be capitalized :
function Person() {
this.first = 'John';
this.last = 'Oliver';
this.fullName = function(){
return this.first + this.last;
};
}
Finally, there can be good reasons to use the this keyword, and that is prototypical inheritance. However, I find the constructor syntax to be misleading in that regard. Fortunately, now we have Object.create:
var personPrototype = {
fullName: function () {
return this.first + this.last;
}
};
function makePerson(first,last) {
var person = Object.create(personPrototype);
person.first = first;
person.last = last;
return person;
}
As a last warning, here is an example of how using this can lead to unanticipated constraints and confusion :
var cn = makePerson("Chuck","Norris");
// works fine
console.log(cn.fullName());
// does not work, fullName is not a first-class function. You cannot detach it.
var fullName = cn.fullName;
console.log(fullName());
Related
In the functional inheritance pattern, Crockford introduces a new superior method via:
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function () {
return method.apply(that, arguments);
};
});
Where method is :
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Example:
var coolcat = function (spec) {
var that = cat(spec),
super_get_name = that.superior('get_name');
that.get_name = function (n) {
return 'like ' + super_get_name() + ' baby';
};
return that;
};
My question is Why don't just assign that.get_name to super_get_name ?
"My question is Why don't just assign that.get_name to super_get_name?"
Because the way the get_name method has its this value set to the that object is by invoking it as:
that.get_name();
When a function is invoked as the method of an object, the object becomes the value of this in that invocation of the function.
If you had done this instead:
var super_get_name = that.get_name;
super_get_name();
Now you're invoking a detached function, so it doesn't know what its this value should be, and so it uses the default, which is usually the window object.
I don't like the solution that crockford shows at all. Typically, in that situation, you'd simply make a new function right there instead of relying on extensions to Object.prototype to do it for you. (Extending Object.prototype is very ugly IMO.)
var coolcat = function (spec) {
var that = cat(spec),
_original_get_name = that.get_name,
super_get_name = function() {
return _original_get_name.apply(that, arguments);
};
that.get_name = function (n) {
return 'like ' + super_get_name() + ' baby';
};
return that;
};
Or in modern implementations, you'd use Function.prototype.bind to create a new function with its this value bound to whatever you provided as the first argument to .bind().
var coolcat = function (spec) {
var that = cat(spec),
super_get_name = that.get_name.bind(that);
that.get_name = function (n) {
return 'like ' + super_get_name() + ' baby';
};
return that;
};
In the sense of Crockford's Functional Inheritance Pattern it is completely valid to reference the base class method
var super_get_name = that.get_name;
This is how Crockford teaches it in his lecture JavaScript Master Class , see the part on Functional Inheritance.
Later - the method might be overriden by the derived class - you invoke it simply
super_get_name();
Crockford's superior method makes no sense in the Functional Inheritance Pattern.
Because in my opinion this is never needed in a method defined by a producer function. If you use this in your methods you'll run in all sorts of trouble because of dynamic scoping and manipulation of this:
function mammal(spec){
var that = {};
that.legs = Math.round(Math.random() * 4);
that.get_name = function(){
return spec.name + "with" + that.legs; // always use that not this
};
that.isProperThis = function(){
console.log( this === that );
};
return that;
};
var myMammal = mammal({name: 'Herb'});
myMammal.isProperThis(); // true
myMammal.isProperThis.call(window); // false
setTimeout(myMammal.isProperThis, 1); // false
If you insist on using this in your methods you can no longer treat them as "first-class" variables in JavaScript. Instead you have to convert them to "binders" by calling bind as described in the first answer in this post.
superior is a method defined in the prototype of the Object constructor function. It caches an object's method, so that it returns the original method even if it were changed later.
From JavaScript: The Good Parts, p.54:
The function will invoke the original method even if the property is changed.
The accepted answer given by cookie monster is correct, but I would like to add clarification.
As cookie monster says, if you write
var super_get_name = that.get_name;
invocation of super_get_name will no longer bind any value to this, making it an unbound function.
However, in the case of the example Crockford gives in The Good Parts, it would not matter if super_get_name were unbound by writing it in the way you propose, because this would never be used in its invocation.
You would essentially end up doing the following:
super_get_name = function () {
return that.says() + ' ' + spec.name +
' ' + that.says();
(where the right operand executes in the context of the function assigned to cat).
I assume that Crockford avoids unbound functions here to demonstrate a general principle, even though his specific example does not require binding.
With respect to JS, what's the difference between the two? I know methods are associated with objects, but am confused what's the purpose of functions? How does the syntax of each of them differ?
Also, what's the difference between these 2 syntax'es:
var myFirstFunc = function(param) {
//Do something
};
and
function myFirstFunc(param) {
//Do something
};
Also, I saw somewhere that we need to do something like this before using a function:
obj.myFirstFunc = myFirstFunc;
obj.myFirstFunc("param");
Why is the first line required, and what does it do?
Sorry if these are basic questions, but I'm starting with JS and am confused.
EDIT: For the last bit of code, this is what I'm talking about:
// here we define our method using "this", before we even introduce bob
var setAge = function (newAge) {
this.age = newAge;
};
// now we make bob
var bob = new Object();
bob.age = 30;
// and down here we just use the method we already made
bob.setAge = setAge;
To answer your title question as to what is the difference between a 'function' and a 'method'.
It's semantics and has to do with what you are trying to express.
In JavaScript every function is an object. An object is a collection of key:value pairs. If a value is a primitive (number, string, boolean), or another object, the value is considered a property. If a value is a function, it is called a 'method'.
Within the scope of an object, a function is referred to as a method of that object. It is invoked from the object namespace MyObj.theMethod(). Since we said that a function is an object, a function within a function can be considered a method of that function.
You could say things like “I am going to use the save method of my object.” And "This save method accepts a function as a parameter.” But you generally wouldn't say that a function accepts a method as a parameter.
Btw, the book JavaScript Patterns by Stoyan Stefanov covers your questions in detail, and I highly recommend it if you really want to understand the language. Here's a quote from the book on this subject:
So it could happen that a function A, being an object, has properties and methods, one of which happens to be another function B. Then B can accept a function C as an argument and, when executed, can return another function D.
There is a slight difference -
Method : Method is a function when object is associated with it.
var obj = {
name : "John snow",
work : function someFun(paramA, paramB) {
// some code..
}
Function : When no object is associated with it , it comes to function.
function fun(param1, param2){
// some code...
}
Many answers are saying something along the lines that a method is what a function is called when it is defined on an object.
While this is often true in the way the word is used when people talk about JavaScript or object oriented programming in general (see here), it is worth noting that in ES6 the term method has taken on a very specific meaning (see section 14.3 Method Definitions of the specs).
Method Definitions
A method (in the strict sense) is a function that was defined through the concise method syntax in an object literal or as a class method in a class declaration / expression:
// In object literals:
const obj = {
method() {}
};
// In class declarations:
class MyClass {
method() {}
}
Method Specificities
This answer gives a good overview about the specificities of methods (in the strict sense), namely:
methods get assigned an internal [[HomeObject]] property which allows them to use super.
methods are not created with a prototype property and they don't have an internal [[Construct]] method which means that they cannot be called with new.
the name of a method does not become a binding in the method's scope.
Below are some examples illustrating how methods (in the strict sense) differ from functions defined on objects through function expressions:
Example 1
const obj = {
method() {
super.test; // All good!
},
ordinaryFunction: function ordinaryFunction() {
super.test; // SyntaxError: 'super' keyword unexpected here
}
};
Example 2
const obj = {
method() {},
ordinaryFunction: function ordinaryFunction() {}
};
console.log( obj.ordinaryFunction.hasOwnProperty( 'prototype' ) ); // true
console.log( obj.method.hasOwnProperty( 'prototype' ) ); // false
new obj.ordinaryFunction(); // All good !
new obj.method(); // TypeError: obj.method is not a constructor
Example 3
const obj = {
method() {
console.log( method );
},
ordinaryFunction: function ordinaryFunction() {
console.log( ordinaryFunction );
}
};
obj.ordinaryFunction() // All good!
obj.method() // ReferenceError: method is not defined
A method is a property of an object whose value is a function. Methods are called on objects in the following format: object.method().
//this is an object named developer
const developer = {
name: 'Andrew',
sayHello: function () {
console.log('Hi there!');
},
favoriteLanguage: function (language) {
console.log(`My favorite programming language is ${language}`);
}
};
// favoriteLanguage: and sayHello: and name: all of them are proprieties in the object named developer
now lets say you needed to call favoriteLanguage propriety witch is a function inside the object..
you call it this way
developer.favoriteLanguage('JavaScript');
// My favorite programming language is JavaScript'
so what we name this: developer.favoriteLanguage('JavaScript');
its not a function its not an object? what it is? its a method
Your first line, is creating an object that references a function. You would reference it like this:
myFirstFunc(param);
But you can pass it to another function since it will return the function like so:
function mySecondFunction(func_param){}
mySecondFunction(myFirstFunc);
The second line just creates a function called myFirstFunc which would be referenced like this:
myFirstFunc(param);
And is limited in scope depending on where it is declared, if it is declared outside of any other function it belongs to the global scope. However you can declare a function inside another function. The scope of that function is then limited to the function its declared inside of.
function functionOne(){
function functionTwo(){}; //only accessed via the functionOne scope!
}
Your final examples are creating instances of functions that are then referenced though an object parameter. So this:
function myFirstFunc(param){};
obj.myFirst = myFirstFunc(); //not right!
obj.myFirst = new myFirstFunc(); //right!
obj.myFirst('something here'); //now calling the function
Says that you have an object that references an instance of a function. The key here is that if the function changes the reference you stored in obj.myFirst will not be changed.
While #kevin is basically right there is only functions in JS you can create functions that are much more like methods then functions, take this for example:
function player(){
this.stats = {
health: 0,
mana: 0,
get : function(){
return this;
},
set : function( stats ){
this.health = stats.health;
this.mana = stats.mana;
}
}
You could then call player.stats.get() and it would return to you the value of heath, and mana. So I would consider get and set in this instance to be methods of the player.stats object.
A function executes a list of statements example:
function add() {
var a = 2;
var b = 3;
var c = a + b;
return c;
}
1) A method is a function that is applied to an object example:
var message = "Hello world!";
var x = message.toUpperCase(); // .toUpperCase() is a built in function
2) Creating a method using an object constructor. Once the method belongs to the object you can apply it to that object. example:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.name = function() {return this.firstName + " " + this.lastName;};
}
document.getElementById("demo").innerHTML = person.fullName(); // using the
method
Definition of a method: A method is a property of an object that is a function. Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object.
var myFirstFunc = function(param) {
//Do something
};
and
function myFirstFunc(param) {
//Do something
};
are (almost) identical. The second is (usually) just shorthand. However, as this jsfiddle (http://jsfiddle.net/cu2Sy/) shows, function myFirstFunc will cause the function to be defined as soon as the enclosing scope is entered, whereas myFirstFunc = function will only create it once execution reaches that line.
As for methods, they have a this argument, which is the current object, so:
var obj = {};
obj.func = function( ) {
// here, "this" is obj
this.test = 2;
}
console.log( obj.test ); // undefined
obj.func( );
console.log( obj.test ); // 2
The exact syntax you showed is because you can also do this:
function abc( ) {
this.test = 2;
}
var obj = {};
obj.func = abc;
obj.func( ); // sets obj.test to 2
but you shouldn't without good reason.
ecma document
4.3.31method :
function that is the value of a property
NOTE When a function is called as a method of an object, the object is
passed to the function as its this value.
It is very clear: when you call a function if it implicitly has a this (to point an object) and if you can't call the function without an object, the function deserves to name as method.
In javascript say I have:
var Person = (function () {
function Person(data) {
data = $.extend({
name: "",
age: 0
}, data);
this.name = data.name;
this.age = data.age;
}
return Person;
})();
Person.prototype.getName = function () {
return this.name;
};
...if I understand the 'this' keyword correctly in javascript, it can refer to pretty much anything from the window object to itself to anything in-between (e.g. callers of the object). My question is how the heck do I write methods like .getName() so that I know I'll always have a reference to the value stored in the person object's name property if I never can be sure what 'this' will refer to in that method? Say that .getName() is called and 'this' references the window object - how the do I get the value I need then?
I'm asking because I've inherited some code using pretty heavy prototyping and I'm running into all kinds of issues trying to reference properties and methods on objects from within themselves. Seems like I'm missing something but I've been looking into scope, closures, and other patterns all day and I can't get around this.
The value of this is set by the language according to how a function/method is called.
If you have an object with a method and you do:
obj.method()
Then, this will be set to point to the object inside of the method() function.
But, if you just get that method by itself like this:
var p = obj.method;
p();
Then, because there is no object reference in the actual function call, this will be set to either window or undefined depending upon whether you are in strict mode or not.
Additionally, the caller can specify exactly what they want this to be set to using obj.method.call() or obj.method.apply() or even p.call() or p.apply() from the previous example. You can look these methods up on MDN to see more details about how they work.
So, in your previous code, this should work:
function Person(data) {
data = $.extend({
name: "",
age: 0
}, data);
this.name = data.name;
this.age = data.age;
}
Person.prototype.getName = function () {
return this.name;
};
var p = new Person({name:"John"});
var n = p.getName(); // will return "John"
Working demo: http://jsfiddle.net/jfriend00/a7MkP/
If you needed to pass getName() to a third party library that won't call it with the object context, then there are a few options like this:
Anonymous function:
var myPerson = new Person("John");
callThirdParty(function() {
// callback that calls getName with the right object context
return myPerson.getName();
});
Using .bind() (not suported in some older browsers):
var myPerson = new Person("John");
var boundFn = myPerson.getName.bind(myPerson);
callThirdParty(boundFn);
From your own method:
var self = this;
callThirdParty(function() {
// callback that calls getName with the right object context
return self.getName();
});
FYI, there really is no reason for the self-executing function you have surrounding your Person constructor function. It just makes the code more complicated and adds no value in this case.
Yes, you are understanding the this keyword correctly.
how the heck do I write methods like .getName() so that I know I'll always have a reference to the value stored in the person object's name property
You can only do so by not using this, and in not using prototyping. Give each object a unique function that always refers to the original object:
function Person(data) {
data = $.extend({
name: "",
age: 0
}, data);
this.name = data.name;
this.age = data.age;
var that = this; // a reference variable always pointing to this instance
this.getName = function() {
// using the variable from the constructor closure
return that.name; // a quite useless getter
};
}
var john = new Person({name:"John"}),
getter = john.getName;
getter(); // "John"
I'm running into all kinds of issues trying to reference properties and methods on objects from within themselves
So with the above you can solve it by making all methods instance-specific. However, that undoes all the advantages of prototyping, and should not be used.
Instead, the one who calls a function (or a method) should be responsible to call it in the correct context:
john.getName();
If you really have to pass a function to someone which ignores that (like addEventListener), you can use magic stuff like .bind() or just apply the above pattern:
// from
addEventListener("click", john.sayHello); // will call the function in context of the DOM
// to
addEventListener("click", function() {
john.sayHello(); // correct thisValue
});
I thought I understood the concept of the JavaScript prototype object, as well as [[proto]] until I saw a few posts regarding class inheritance.
Firstly, "JavaScript OOP - the smart way" at http://amix.dk/blog/viewEntry/19038
See the implementation section:
var parent = new this('no_init');
And also "Simple JavaScript Inheritance" on John Resig's great blog.
var prototype = new this();
What does new this(); actually mean?
This statement makes no sense to me because my understand has been that this points to an object and not a constructor function. I've also tried testing statements in Firebug to figure this one out and all I receive is syntax errors.
My head has gone off into a complete spin.
Could someone please explain this in detail?
In a javascript static function, you can call new this() like so,
var Class = function(){}; // constructor
Class.foo = function(){return this;} // will return the Class function which is also an object
Therefore,
Class.foo = function(){ return new this();} // Will invoke the global Class func as a constructor
This way you get a static factory method. The moral of the story is, not to forget functions are just like any other objects when you are not calling them.
What is confusing you, I think, is just where "this" is really coming from. So bear with me-- here is a very brief explanation that I hope will make it quite clear.
In JavaScript, what "this" refers to within a function is always determined at the time the function is called. When you do:
jimmy.nap();
The nap function (method) runs and receives jimmy as "this".
What objects have references to nap is irrelevant. For example:
var jimmy = {}, billy = {};
jimmy.nap = function(){ alert("zzz"); };
var jimmy_nap = jimmy.nap;
jimmy_nap(); // during this function's execution, this is *NOT* jimmy!
// it is the global object ("window" in browsers), which is given as the
// context ("this") to all functions which are not given another context.
billy.sleep = jimmy.nap;
billy.sleep(); // during this function's excution, this is billy, *NOT* jimmy
jimmy.nap(); //okay, this time, this is jimmy!
In other words, whenever you have:
var some_func = function(arg1, arg2){ /*....*/ };
// let's say obj and other_obj are some objects that came from somewhere or another
obj.some_meth = some_func;
other_obj.some_meth = some_func;
obj.some_meth(2, 3);
other_obj.some_meth(2, 3);
What it's getting "translated" into (not literally-- this is pedagogical, not about how javascript interpreters actually work at all) is something like:
var some_func = function(this, arg1, arg2){ /* ...*/ };
// let's say obj and other_obj are some objects that came from somewhere or another
obj.some_meth = some_func;
other_obj.some_meth = some_func;
obj.some_meth(obj, 2, 3);
other_obj.some_meth(other_obj, 2, 3);
So, notice how extend is used in the example on that page:
UniversityPerson = Person.extend({ /* ... */ });
Pop quiz: When extend runs, what does it think "this" refers to?
Answer: That's right. "Person".
So the puzzling code above really is the same as (in that particular case):
var prototype = new Person('no_init');
Not so mysterious anymore, eh? This is possible because unlike in some languages,
a JavaScript variable-- including "this"-- can hold any value, including a function such as Person.
(There is nothing that makes Person specifically a constructor. Any function can be invoked with the new keyword. If I recall the exact semantics, I think they are that when a function is called with the new keyword, it is automatically given an empty object ({}) as its context ("this") and when the function returns, the return value is that same object unless (maybe?) the function returns something else)
This is a cool question because it speaks to a pretty essential part of JavaScript's neatness or oddness (depending on how you see it).
Does that answer your question? I can clarify if necessary.
AJS.Class effectively* translates this:
var Person = new AJS.Class({
init: function(name) {
this.name = name;
Person.count++;
},
getName: function() {
return this.name;
}
});
Person.count = 0;
into this:
var Person = function (name) {
this.name = name;
Person.count++;
};
Person.prototype = {
getName: function() {
return this.name;
}
};
Person.extend = AJS.Class.prototype.extend;
Person.implement = AJS.Class.prototype.implement;
Person.count = 0;
Therefore, in this case, this in AJS.Class.prototype.extend refers to Person, because:
Person.extend(...);
// is the same as
Person.extend.call(Person, ...);
// is the same as
AJS.Class.prototype.extend.call(Person, ...);
* There are a lot of cases I don't go over; this rewrite is for simplicity in understanding the problem.
Imagine the following situation :
var inner = function () {
var obj = new this;
console.log(obj.myProperty);
};
var f1 = function () {
this.myProperty = "my Property"
}
f1.f2 = inner;
f1.f2();
Here the calling object is itself a function, so this will return a function, and we can instantiate it.
In order to use this()(not this) the outer function(the context) must itself return smth that can be instantiated(another function):
var inner = function () {
var obj = new this();
console.log(obj.myProperty);
};
var f1 = function () {
var func = function () {};
func.myProperty = 'my property';
return func;
};
f1.f2 = inner;
f1.f2();
A simpler code explaination:
class User {
constructor() {
this.name = '';
this.age = '';
}
static getInfo() {
let user = new this();
console.log(user);
}
}
User.getInfo()
Output:
Object {
age: "",
name: ""
}
see this link http://www.quirksmode.org/js/this.html It will tell you about the this keyword, but I am not sure what this() is, may be its some kind of user defined function...... that you are not aware of...
"this" means the context of the function currently running.
The code you are posting surely appears in a function that act as a method for an object.
So the object is the context of the function.
"new this()" will return a clone of the current object after running its constructor function with the passed arguments.
this() refers to the the function that the code is in, but this() would have to be within that function. Calling new this(); within a function would create a never ending loop. Calling it outside of a function would be redundant because there is no function/class set as this().
Normally, I've seen prototype functions declared outside the class definition, like this:
function Container(param) {
this.member = param;
}
Container.prototype.stamp = function (string) {
return this.member + string;
}
var container1 = new Container('A');
alert(container1.member);
alert(container1.stamp('X'));
This code produces two alerts with the values "A" and "AX".
I'd like to define the prototype function INSIDE of the class definition. Is there anything wrong with doing something like this?
function Container(param) {
this.member = param;
if (!Container.prototype.stamp) {
Container.prototype.stamp = function() {
return this.member + string;
}
}
}
I was trying this so that I could access a private variable in the class. But I've discovered that if my prototype function references a private var, the value of the private var is always the value that was used when the prototype function was INITIALLY created, not the value in the object instance:
Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) {
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}
var container1 = new Container('A');
var container2 = new Container('B');
alert(container1.stamp('X'));
alert(container2.stamp('X'));
This code produces two alerts with the values "AAX" and "ABX". I was hoping the output would be "AAX" and "BBX". I'm curious why this doesn't work, and if there is some other pattern that I could use instead.
EDIT: Note that I fully understand that for this simple example it would be best to just use a closure like this.stamp = function() {} and not use prototype at all. That's how I would do it too. But I was experimenting with using prototype to learn more about it and would like to know a few things:
When does it make sense to use prototype functions instead of closures? I've only needed to use them to extend existing objects, like Date. I've read that closures are faster.
If I need to use a prototype function for some reason, is it "OK" to define it INSIDE the class, like in my example, or should it be defined outside?
I'd like to understand why the privateVar value of each instance is not accessible to the prototype function, only the first instance's value.
When does it make sense to use prototype functions instead of closures?
Well, it's the most lightweight way to go, let's say you have a method in the prototype of certain constructor, and you create 1000 object instances, all those objects will have your method in their prototype chain, and all of them will refer to only one function object.
If you initialize that method inside the constructor, e.g. (this.method = function () {};), all of your 1000 object instances will have a function object as own property.
If I need to use a prototype function for some reason, is it "OK" to define it INSIDE the class, like in my example, or should it be defined outside?
Defining the members of a constructor's prototype inside itself, doesn't makes much sense, I'll explain you more about it and why your code doesn't works.
I'd like to understand why the privateVar value of each instance is not accessible to the prototype function, only the first instance's value.
Let's see your code:
var Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) { // <-- executed on the first call only
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}
The key point about your code behavior is that the Container.prototype.stamp function is created on the first method invocation.
At the moment you create a function object, it stores the current enclosing scope in an internal property called [[Scope]].
This scope is later augmented when you call the function, by the identifiers (variables) declared within it using var or a FunctionDeclaration.
A list of [[Scope]] properties forms the scope chain, and when you access an identifier (like your privateVar variable), those objects are examined.
And since your function was created on the first method invocation (new Container('A')), privateVar is bound to the Scope of this first function call, and it will remain bound to it no matter how do you call the method.
Give a look to this answer, the first part is about the with statement, but in the second part I talk about how the scope chain works for functions.
Sorry for resurrecting an old question, but I wanted to add something that I recently discovered somewhere else here on SO (looking for the link, will edit/add it once I find it): found it.
I personally like the below methodology because I can visually group all my prototype and 'instance' definitions together with the function definition, while avoiding evaluating them more than once. It also provides an opportunity to do closures with your prototype methods, which can be useful for creating 'private' variables shared by different prototype methods.
var MyObject = (function () {
// Note that this variable can be closured with the 'instance' and prototype methods below
var outerScope = function(){};
// This function will ultimately be the "constructor" for your object
function MyObject() {
var privateVariable = 1; // both of these private vars are really closures specific to each instance
var privateFunction = function(){};
this.PublicProtectedFunction = function(){ };
}
// "Static" like properties/functions, not specific to each instance but not a prototype either
MyObject.Count = 0;
// Prototype declarations
MyObject.prototype.someFunction = function () { };
MyObject.prototype.someValue = 1;
return MyObject;
})();
// note we do automatic evalution of this function, which means the 'instance' and prototype definitions
// will only be evaluated/defined once. Now, everytime we do the following, we get a new instance
// as defined by the 'function MyObject' definition inside
var test = new MyObject();
You need to put the function on each specific instance instead of the prototype, like this:
Container = function(param) {
this.member = param;
var privateVar = param;
this.stamp = function(string) {
return privateVar + this.member + string;
}
}
To get the behavior you want you need to assign each individual object separate stamp() functions with unique closures:
Container = function(param) {
this.member = param;
var privateVar = param;
this.stamp = function(string) {
return privateVar + this.member + string;
}
}
When you create a single function on the prototype each object uses the same function, with the function closing over the very first Container's privateVar.
By assigning this.stamp = ... each time the constructor is called each object will get its own stamp() function. This is necessary since each stamp() needs to close over a different privateVar variable.
That is because privateVar is not a private member of the object, but part of stamp's closure. You could get the effect by always creating the function:
Container = function(param) {
this.member = param;
var privateVar = param;
this.stamp = function(string) {
return privateVar + this.member + string;
}
}
The value of privateVar is set when the function is built, so you need to create it each time.
EDIT: modified not to set the prototype.