Is it possible to use the statement as shown below to define a method without the use of prototype?
Person.sayHello = function () {...}
On this example
var Person = function (firstName) {
this.firstName = firstName;
};
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.firstName);
};
var person1 = new Person("Alice");
var person2 = new Person("Bob");
In short, no.
Person.sayHello = function () {...};
This line will add a function called "sayHello" to the Person class itself rather than to instances of the Person class. So, it can only be invoked by
Person.sayHello();
rather than by
var matt = new Person('Matt');
matt.sayHello();
// sayHello is not defined on matt
If you are familiar with Java or C#, adding a method to Person in this way is like creating a static method.
However, we can add a method to instances without adding a method to the prototype.
Method 1: Create the "sayHello" function in the constructor of Person
var Person = function (firstName) {
this.firstName = firstName;
this.sayHello = sayHello() {...};
};
This method has the disadvantage that a new function is created for every instance of Person. That is,
var frank = new Person('Frank');
var matt = new Person('Matt');
// frank.sayHello != matt.sayHello;
Thus, this method can be hard on memory. However, it does allow for encapsulation (e.g. private state) via closures. In the following sample, it is impossible to modify the "count" variable outside of the Person class without calling the "sayHello" function.
var Person = function (firstName) {
this.firstName = firstName;
this.sayHello = sayHello() {
count++;
console.log("Hello has been said " + count + "times".
};
var count = 0;
};
Method 2: Create the "sayHello" function outside the constructor of Person and assign it within the constructor of Person
var Person = function (firstName) {
this.firstName = firstName;
this.sayHello = sayHello;
};
function sayHello() {...}
This method has the advantage of lower memory usage; there is only one instance of the sayHello function, and it is shared across instances of Person. That is,
var frank = new Person('Frank');
var matt = new Person('Matt');
// frank.sayHello == matt.sayHello;
This makes it similar to the prototype method. However, the assignment of the function to each instance still consumes more memory than the prototype method where the function is only assigned to the prototype object.
However, like the prototype method, this method does not allow for private state. All state must be accessed through public state exposed via the this keyword.
Update: Clarification of the difference in memory usage between method 1 and method 2.
Method 1 is like this:
var function1 = function() { console.log('Hello'); };
var function2 = function() { console.log('Hello'); };
The functions have the same behavior, but are not equal. JavaScript doesn't know they are functionally similar, so it creates two functions in memory to represent them.
Method 2 is like this:
var sayHello = function() { console.log('Hello'); };
var function1 = sayHello;
var function2 = sayHello;
Now function1 and function2 are actually the same function because they both simply hold a reference to sayHello.
Update: Example usage of a module pattern to avoid adding "sayHello" to the global scope in method 2.
This module defines the Person class in a module defined by an anonymous closure (a self executing function) and exports it to the global scope. Because "sayHello" is defined in the closure of the module and is not exported, it is not added to the global scope.
var Person = (function () {
function Person(firstName) {
this.firstName = firstName;
this.sayHello = sayHello;
};
function sayHello() {...}
return Person;
}());
Yes, you can. If you come from traditional OO background, it might help to think about this as effectively behaving like a public static property on a class.
As jsdeveloper said in the above comment. Functions are just objects that can be executed. You can add properties to them just like any other object. This technique is actually used in practice for patterns like memoization or currying.
In your case sayHello can accessed anywhere the Person function can be accessed. It's not really related to inheritance/prototype since it doesn't have to do with resolving properties by traversing the prototype chain, but it is another way to make data accessible.
I'm sure it varies based on the developer, but I often put pure functions which don't reference this as static methods as you have done since they are easier to test and make the intention clear to other developers
It would be weird, but if you really need to do it that way, you can assign the function to its own prototype once, then add all of the functions to the main function.
var Person = function (firstName) {
this.firstName = firstName;
};
Person.prototype = Person;
Person.sayHello = function() {
console.log("Hello, I'm " + this.firstName);
};
Yes you can but the sayhello function will not be able to access any of the object properties (ie this.myvar) and you can only call it like a static method:
Person.sayhello()
(and not mypersonobject.sayhello).
When you extend the prototype, the sayhello function is available to all Person objects created using the 'new' keyword in the usual fashion.
https://jsfiddle.net/jsheridan390/kL7arrqs/
Related
What is the difference between the following two declarations?
Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }
Is it okay to think of the first statement as a declaration of a static method, and the second statement as a declaration of an instance method?
Yes, the first function has no relationship with an object instance of that constructor function, you can consider it like a 'static method'.
In JavaScript functions are first-class objects, that means you can treat them just like any object, in this case, you are only adding a property to the function object.
The second function, as you are extending the constructor function prototype, it will be available to all the object instances created with the new keyword, and the context within that function (the this keyword) will refer to the actual object instance where you call it.
Consider this example:
// constructor function
function MyClass () {
var privateVariable; // private member only available within the constructor fn
this.privilegedMethod = function () { // it can access private members
//..
};
}
// A 'static method', it's just like a normal function
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};
MyClass.prototype.publicMethod = function () {
// the 'this' keyword refers to the object instance
// you can access only 'privileged' and 'public' members
};
var myObj = new MyClass(); // new object instance
myObj.publicMethod();
MyClass.staticMethod();
Yes, the first one is a static method also called class method, while the second one is an instance method.
Consider the following examples, to understand it in more detail.
In ES5
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.isPerson = function(obj) {
return obj.constructor === Person;
}
Person.prototype.sayHi = function() {
return "Hi " + this.firstName;
}
In the above code, isPerson is a static method, while sayHi is an instance method of Person.
Below, is how to create an object from Person constructor.
var aminu = new Person("Aminu", "Abubakar");
Using the static method isPerson.
Person.isPerson(aminu); // will return true
Using the instance method sayHi.
aminu.sayHi(); // will return "Hi Aminu"
In ES6
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
static isPerson(obj) {
return obj.constructor === Person;
}
sayHi() {
return `Hi ${this.firstName}`;
}
}
Look at how static keyword was used to declare the static method isPerson.
To create an object of Person class.
const aminu = new Person("Aminu", "Abubakar");
Using the static method isPerson.
Person.isPerson(aminu); // will return true
Using the instance method sayHi.
aminu.sayHi(); // will return "Hi Aminu"
NOTE: Both examples are essentially the same, JavaScript remains a classless language. The class introduced in ES6 is primarily a syntactical sugar over the existing prototype-based inheritance model.
When you create more than one instance of MyClass , you will still only have only one instance of publicMethod in memory but in case of privilegedMethod you will end up creating lots of instances and staticMethod has no relationship with an object instance.
That's why prototypes save memory.
Also, if you change the parent object's properties, is the child's corresponding property hasn't been changed, it'll be updated.
For visual learners, when defining the function without .prototype
ExampleClass = function(){};
ExampleClass.method = function(customString){
console.log((customString !== undefined)?
customString :
"called from func def.");}
ExampleClass.method(); // >> output: `called from func def.`
var someInstance = new ExampleClass();
someInstance.method('Called from instance');
// >> error! `someInstance.method is not a function`
With same code, if .prototype is added,
ExampleClass.prototype.method = function(customString){
console.log((customString !== undefined)?
customString :
"called from func def.");}
ExampleClass.method();
// > error! `ExampleClass.method is not a function.`
var someInstance = new ExampleClass();
someInstance.method('Called from instance');
// > output: `Called from instance`
To make it clearer,
ExampleClass = function(){};
ExampleClass.directM = function(){} //M for method
ExampleClass.prototype.protoM = function(){}
var instanceOfExample = new ExampleClass();
ExampleClass.directM(); ✓ works
instanceOfExample.directM(); x Error!
ExampleClass.protoM(); x Error!
instanceOfExample.protoM(); ✓ works
****Note for the example above, someInstance.method() won't be executed as,
ExampleClass.method() causes error & execution cannot continue.
But for the sake of illustration & easy understanding, I've kept this sequence.****
Results generated from chrome developer console & JS Bin
Click on the jsbin link above to step through the code.
Toggle commented section with ctrl+/
A. Static Method:
Class.method = function () { /* code */ }
method() here is a function property added to an another function (here Class).
You can directly access the method() by the class / function name. Class.method();
No need for creating any object/instance (new Class()) for accessing the method(). So you could call it as a static method.
B. Prototype Method (Shared across all the instances):
Class.prototype.method = function () { /* code using this.values */ }
method() here is a function property added to an another function protype (here Class.prototype).
You can either directly access by class name or by an object/instance (new Class()).
Added advantage - this way of method() definition will create only one copy of method() in the memory and will be shared across all the object's/instance's created from the Class
C. Class Method (Each instance has its own copy):
function Class () {
this.method = function () { /* do something with the private members */};
}
method() here is a method defined inside an another function (here Class).
You can't directly access the method() by the class / function name. Class.method();
You need to create an object/instance (new Class()) for the method() access.
This way of method() definition will create a unique copy of the method() for each and every objects created using the constructor function (new Class()).
Added advantage - Bcos of the method() scope it has the full right to access the local members(also called private members) declared inside the constructor function (here Class)
Example:
function Class() {
var str = "Constructor method"; // private variable
this.method = function () { console.log(str); };
}
Class.prototype.method = function() { console.log("Prototype method"); };
Class.method = function() { console.log("Static method"); };
new Class().method(); // Constructor method
// Bcos Constructor method() has more priority over the Prototype method()
// Bcos of the existence of the Constructor method(), the Prototype method
// will not be looked up. But you call it by explicity, if you want.
// Using instance
new Class().constructor.prototype.method(); // Prototype method
// Using class name
Class.prototype.method(); // Prototype method
// Access the static method by class name
Class.method(); // Static method
What is the difference between the following two declarations?
Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }
Is it okay to think of the first statement as a declaration of a static method, and the second statement as a declaration of an instance method?
Yes, the first function has no relationship with an object instance of that constructor function, you can consider it like a 'static method'.
In JavaScript functions are first-class objects, that means you can treat them just like any object, in this case, you are only adding a property to the function object.
The second function, as you are extending the constructor function prototype, it will be available to all the object instances created with the new keyword, and the context within that function (the this keyword) will refer to the actual object instance where you call it.
Consider this example:
// constructor function
function MyClass () {
var privateVariable; // private member only available within the constructor fn
this.privilegedMethod = function () { // it can access private members
//..
};
}
// A 'static method', it's just like a normal function
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};
MyClass.prototype.publicMethod = function () {
// the 'this' keyword refers to the object instance
// you can access only 'privileged' and 'public' members
};
var myObj = new MyClass(); // new object instance
myObj.publicMethod();
MyClass.staticMethod();
Yes, the first one is a static method also called class method, while the second one is an instance method.
Consider the following examples, to understand it in more detail.
In ES5
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.isPerson = function(obj) {
return obj.constructor === Person;
}
Person.prototype.sayHi = function() {
return "Hi " + this.firstName;
}
In the above code, isPerson is a static method, while sayHi is an instance method of Person.
Below, is how to create an object from Person constructor.
var aminu = new Person("Aminu", "Abubakar");
Using the static method isPerson.
Person.isPerson(aminu); // will return true
Using the instance method sayHi.
aminu.sayHi(); // will return "Hi Aminu"
In ES6
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
static isPerson(obj) {
return obj.constructor === Person;
}
sayHi() {
return `Hi ${this.firstName}`;
}
}
Look at how static keyword was used to declare the static method isPerson.
To create an object of Person class.
const aminu = new Person("Aminu", "Abubakar");
Using the static method isPerson.
Person.isPerson(aminu); // will return true
Using the instance method sayHi.
aminu.sayHi(); // will return "Hi Aminu"
NOTE: Both examples are essentially the same, JavaScript remains a classless language. The class introduced in ES6 is primarily a syntactical sugar over the existing prototype-based inheritance model.
When you create more than one instance of MyClass , you will still only have only one instance of publicMethod in memory but in case of privilegedMethod you will end up creating lots of instances and staticMethod has no relationship with an object instance.
That's why prototypes save memory.
Also, if you change the parent object's properties, is the child's corresponding property hasn't been changed, it'll be updated.
For visual learners, when defining the function without .prototype
ExampleClass = function(){};
ExampleClass.method = function(customString){
console.log((customString !== undefined)?
customString :
"called from func def.");}
ExampleClass.method(); // >> output: `called from func def.`
var someInstance = new ExampleClass();
someInstance.method('Called from instance');
// >> error! `someInstance.method is not a function`
With same code, if .prototype is added,
ExampleClass.prototype.method = function(customString){
console.log((customString !== undefined)?
customString :
"called from func def.");}
ExampleClass.method();
// > error! `ExampleClass.method is not a function.`
var someInstance = new ExampleClass();
someInstance.method('Called from instance');
// > output: `Called from instance`
To make it clearer,
ExampleClass = function(){};
ExampleClass.directM = function(){} //M for method
ExampleClass.prototype.protoM = function(){}
var instanceOfExample = new ExampleClass();
ExampleClass.directM(); ✓ works
instanceOfExample.directM(); x Error!
ExampleClass.protoM(); x Error!
instanceOfExample.protoM(); ✓ works
****Note for the example above, someInstance.method() won't be executed as,
ExampleClass.method() causes error & execution cannot continue.
But for the sake of illustration & easy understanding, I've kept this sequence.****
Results generated from chrome developer console & JS Bin
Click on the jsbin link above to step through the code.
Toggle commented section with ctrl+/
A. Static Method:
Class.method = function () { /* code */ }
method() here is a function property added to an another function (here Class).
You can directly access the method() by the class / function name. Class.method();
No need for creating any object/instance (new Class()) for accessing the method(). So you could call it as a static method.
B. Prototype Method (Shared across all the instances):
Class.prototype.method = function () { /* code using this.values */ }
method() here is a function property added to an another function protype (here Class.prototype).
You can either directly access by class name or by an object/instance (new Class()).
Added advantage - this way of method() definition will create only one copy of method() in the memory and will be shared across all the object's/instance's created from the Class
C. Class Method (Each instance has its own copy):
function Class () {
this.method = function () { /* do something with the private members */};
}
method() here is a method defined inside an another function (here Class).
You can't directly access the method() by the class / function name. Class.method();
You need to create an object/instance (new Class()) for the method() access.
This way of method() definition will create a unique copy of the method() for each and every objects created using the constructor function (new Class()).
Added advantage - Bcos of the method() scope it has the full right to access the local members(also called private members) declared inside the constructor function (here Class)
Example:
function Class() {
var str = "Constructor method"; // private variable
this.method = function () { console.log(str); };
}
Class.prototype.method = function() { console.log("Prototype method"); };
Class.method = function() { console.log("Static method"); };
new Class().method(); // Constructor method
// Bcos Constructor method() has more priority over the Prototype method()
// Bcos of the existence of the Constructor method(), the Prototype method
// will not be looked up. But you call it by explicity, if you want.
// Using instance
new Class().constructor.prototype.method(); // Prototype method
// Using class name
Class.prototype.method(); // Prototype method
// Access the static method by class name
Class.method(); // Static method
I have a View class that has a constructor method initialize I think this is a constructor method, correct me if wrong.
var View = function(obj) {
this.initalize = obj.initalize;
};
What I would like to achieve is something gets called when the Class is instantiated.
How can I pass in an object like so?
var chatView = new View({
initialize: function() {
alert('Yay for initialization');
}
});
So that when I instantiate the View I can pass an object to the constructor and within a key initialize which value is a function and this key specifically gets called when instantiated.
If I get it right, there is a simple way of achieving what you want:
var View = function(obj) {
obj.initialize();
}
This way, the initialize function gets called whenever you instantiate a View class.
Be aware that if you want to do real "initialization code" inside the initialize function to work, you could use call (or apply):
var View = function(obj) {
if (typeof obj.initialize === 'function') {
obj.initialize.call(this);
}
}
var chatView = new View({
initialize: function() {
this.property = 'property';
}
});
console.log(chatView.property); // outputs property
Javascript doesn't have a constructor, remember that javascript is based on prototype. This is an example of "constructor" you can create
function Example (firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Example.prototype.getFullname = function () {
return this.firstname + ' ' + this.lastname;
}
If you want to create a constructor function you must to call it after you instantiate the function.
But this is a better structure you can use. I recommended only if you need a constructor function and private function. Otherwise, use a simple structure with methods declared with prototype, you can get a better performance.
var MyObject = (function () {
// Constructor
function MyObject (foo) {
this._foo = foo;
}
function privateFun (prefix) {
return prefix + this._foo;
}
MyObject.prototype.publicFun = function () {
return privateFun.call(this, '>>');
}
return MyObject;
})();
var myObject = new MyObject('bar');
With this code you have a constructor, but it's a "private" function, so you can't overwrite it after instantiate the object.
Here I have a link I create testing differents structures:
https://plnkr.co/edit/qzgWVZlnIFnWl0MoUe5n?p=preview
The result:
Test 1: ~15k (with private function) - Recommended ONLY if you want/need a private function
Test 2: ~38k (with private function) - Not recommended, it's returning an object which is really bad.
Test 3: ~8k (without private function) - Recommended, it has the best performance, but you can't create a private function, which means, anybody can call any function :S
I've recently seen JavaScript-code in which getter- and setter-methods where defined on the prototype-object on a constructor method.
For example:
Person.prototype.getFirstName = function() {
return this.firstName;
}
Is this correct?
I mean:
'this' points to the describer of the the object upon which the method was called.
What happens when I call ...
console.log(Person.getFirstName());
... without making an object prior?
Moreover:
Is there a general rule when to attach properties to the constructor-method and when to attach to the prototype-object?
From my view is attaching to the prototype correct if you don't necessarily have to create an object. Because the method doesn't use values of an object which have to set object-individually.
What happens when I call ...
console.log(Person.getFirstName());
... without making an object prior?
You get an error, Person has no getFirstName property.
Is there a general rule when to attach properties to the constructor-method and when to attach to the prototype-object?
Yes:
If you want the method to be available on objects created via the constructor function (e.g., on obj in var obj = new Person()), put the method on the constructor function's prototype object (shared) or assign the method to the object within the constructor by assigning to a property on this (not shared).
If you want the method to be available on the constructor function itself, the way some of the built-in JavaScript methods are (like Date.parse or Object.create), assign it to a property on the constructor:
Person.doSomething = function() {
// ...
};
Those methods are not specific to objects created by the constructor (this within them is a reference to the constructor function itself, unless you do something to make it different).
If you're coming from a class-based language, a very loose analogy is that properties (including methods) you assign to the prototype object on the constructor or to this within the constructor are instance properties, and ones you assign to the constructor itself are static properties. It's a very loose analogy, but sometimes helpful.
Here's a full example in the old ES5 and earlier syntax:
function Person(name) {
this.getName = function() {
return name;
};
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.getName());
};
Person.copy = function(other) {
return new Person(other.getName());
};
// Usage example
var joe = new Person("Joe");
joe.sayHello();
console.log("joe's name is " + joe.getName());
var joeagain = Person.copy(joe);
joeagain.sayHello();
In the above:
getName is available on instances created by new Person. It's created separately for each object and is not shared with other instances. It lets us get the person's name, which in this example is read-only.
sayHello is available on instances created by new Person because they inherit it from their prototype, which is assigned to them by new Person from the Person.prototype property. It's shared between instances.
copy is not available on instances (joe.copy() would be an error), it's a property on Person itself. In this case we use it to copy instances, but it could be for anything.
Prototypes get inherited by instantiating it with new keyword
So the code
var Person = function(){}
Person.prototype.getFirstName = function() {
return this.firstName;
}
Person.prototype.firstName = "test";
console.log(Person.getFirstName()); // Throw Uncaught TypeError
Correct method is:
var Person2 = new Person()
Person2.getFirstName() // "test"
To test this Object:
so Prototype of Person is set to this Object of Person2 (Inheritance)
This is similar to Class as in Java or C# language.
Personally I'm not fond of adding a getter to the prototype if all you want is to access the instance values. You can already access those values via the instance:
function Person(name) {
this.firstname = name;
}
Person.prototype.getFirstname = function() {
return this.firstname;
}
var p = new Person('o-o');
console.log(p.firstname); //o-o
console.log(p.getFirstname()); //o-o
You could add a getter to the prototype to pass a different context:
var firstname = Person.prototype.getFirstname.call({firstname: 'other'});
console.log(firstname); // other
If so it'd make sense to add a getter to the prototype to add up some computation:
Person.prototype.getFirstname = function() {
return new Date().toISOString + ': ' + this.firstname;
};
If that strategy suits your needs, you could orchestrate your code differently:
var common = {
getValue = function(propName) {
return new Date().toISOString() + ': ' + this[propName];
}
};
function Person(name) {
this.firstname = name;
}
$.extend(Person.prototype, common); //jQuery extend
var p = new Person('o-o');
console.log(p.firstname); //o-o
console.log(p.getValue('firstname')); //today: o-o
Extend your prototype with a versatile common: add logging information during development and drop those superfluous logging information in production.
So this is an example of the famous JavaScript Module Pattern:
var Person = (function() {
var _name; // so called 'private variable'
function Person(name) {
_name = name;
}
Person.prototype.kill = function() {
console.log(_name + ' has been shot');
};
return Person;
})();
var paul = new Person('Paul');
paul.kill();
So far so good right? This logs 'Paul has been shot' to the console, which is what we want.
But.
Is _name really a private variable? I would define a private variable as a variable that belongs to an instance of an object, which is not accessible for the outside world. The last part works, I can not access _name from outside the closure.
But if I do this:
var paul = new Person('Paul');
var bran = new Person('Bran');
paul.kill();
bran.kill();
This will then log 'Bran has been shot', twice. No Paul there. So _name is actually shared with all instances of my Person object. That's what I would define as a 'static variable', although it's also not accessible from outside.
So is there any way to create a real private member variable with the module pattern? One that is not static.
Something that also happens a lot is defining this._name inside the constructor function, but that kills the private part, it's now accessible from outside:
function Person(name) {
this._name = name;
}
var bran = new Person();
console.log(bran._name); // yep, accessible
Question:
So. Private is not really private, just static. How do we create a real private member variable with the module pattern? A variable which belongs to an instance, which is not static, and a variable which is not accessible from the outside.
You're right; _name is more of a static variable. It is kept in the closure that contains the constructor, so every use of the constructor will use that same variable. And remember, this has nothing to do with classes, and everything to do with closures and functions. It can be pretty handy, but it isn't how you do private members.
Unsurprisingly, Douglas Crockford has a page devoted to private members in Javascript.
In order to make private members, you have to go 'one level deeper'. Don't use a closure outside of the constructor; use the constructor as the closure. Any variables or methods defined inside the constructor are obviously not usable by the outside world. In fact, they aren't accessible by the object, either, so they are rather extremely 'private'.
We want to use our private members though. :) So what to do?
Well, in the constructor, do this:
var Klass = function () {
var private = 3;
this.privileged = function () { return private; };
};
and then:
var k = Klass();
console.log(k.privileged()); // 3
See how that's using the constructor as a closure? this.privileged lives on, attached to the object, and thus private lives on, inside this.privileged's closure.
Unfortunately, there's one problem with private and privileged methods in Javascript. They must be instantiated from scratch each time. There is no code sharing. That's obviously what we want with private members, but it isn't ideal for methods. Using them slows down object instantiation and uses more memory. It's something to keep in mind when/if you run into efficiency problems.
"Real private member variables" and prototype based methods do not play nice together. The only way achieve what you want is to create all methods in the constructor.
var Person = (function() {
function Person(name) {
this.kill = function() {
console.log(name + ' has been shot');
};
}
return Person;
})();
var paul = new Person('Paul');
var bran = new Person('Bran');
paul.kill(); // Paul has been shot
bran.kill(); // Bran has been shot
But this will use more memory and be slower since each instance has a unique version of the kill function.
Conventionally, the underscore prefix is used for semi-private instance properties, as long as the data exposed is not a security risk. Most consumers of your javascript code know not to mess with underscore prefixed properties.
Some more reading you may find useful is here.
The problem is that your _name variable is outside the Person scope and shared between all Person instances. Do something like the following instead :
(function() {
var Person = function(name) {
var _name = name; // so called 'private variable'
this.getName = function()
{
return _name;
}
this.kill = function()
{
console.log(this.getName() + ' has been shot');
}
}
/*Alternative
Person.prototype.kill = function() {
console.log(this.getName() + ' has been shot');
};*/
window.Person = Person;
})();
var paul = new Person('Paul');
var bran = new Person('Bran');
paul.kill();
bran.kill();
A variable that needs to be private in instance scope has to be in such scope, for example:
function Person(name) {
var _name = name;
this.kill = function() {
console.log( _name + ' has been shot' );
}
}
A drawback of this is that kill has to be defined in a scope that also has access to the private variable.
In order to create a private var, you should put it inside the constructor, so your code would be like this:
var Person = (function() {
function Person(name) {
// since name is a param, you don't even have to create a _name var
// and assign name to it
this.getName = function () {
return name;
};
}
Person.prototype.kill = function() {
console.log(this.getName() + ' has been shot');
};
return Person;
})();
var paul = new Person('Paul');
paul.kill();
You can also declare .kill inside the constructor:
var Person = (function() {
function Person(name) {
this.kill = function() {
console.log(name + ' has been shot');
};
}
return Person;
})();
var paul = new Person('Paul');
paul.kill();