This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 9 years ago.
I have been trying to learn OO JS. I was playing with different patterns, wrote following example.
var obj = function() {
this.a= function() {
return 'a';
}
}
obj.prototype.b = function() {
return 'b';
}
var instance = new obj();
console.log(instance.a());
console.log(instance.b());
Is there any difference here in function a and b?
this.a will be a separate function for every object you create:
var obj = function() {
this.a= function() {
return 'a';
}
}
obj.prototype.b = function() {
return 'b';
}
var instance1 = new obj();
var instance2 = new obj();
console.log(instance1 === instance2); // false: different instances
console.log(instance1.a === instance2.a); // false: different functions (this.a)
console.log(instance1.b === instance2.b); // true: obj.prototype.b
This means that this.a = function(){ ... } will consume memory for every instance, something you most likely want to avoid.
In your code, a is a function of the instance, whereas b is a function of the class.
In terms of them actually working, there isn't much different between them by themselves. However, let's say you put var test = 123; inside the obj function. a will be able to access it, but b will not.
Additionally, you can overwrite instance.a with another function, and it will only affect the current instance.
On the other hand, a is a separate function object for each instance of the object. This could become a problem in terms of memory use if you have large numbers of instances.
Related
This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 4 years ago.
When defining javascript objects that behave like classes that have state and functions that manipulate that state is it better to define functions when defining the object like so:
function MyNewClass(){
//State
this.value = ""
this.otherValue = ""
//Functions
this.someFunction = function(){
//Some logic here
}
}
Or it it better practice to define functions on the prototype of the object such as:
function MyNewClass (){
//state
this.value = ""
this.otherValue = ""
}
MyNewClass.prototype.someFunction = function(){
//Some logic here
}
Are there any advantages to defining object functions on the prototype?
Thanks!
Because functions are objects, given the described scenario, we have two behavior:
If you declare the function on the "class" function, every object you
create then it will have a copy of that function (object), so the
memory usage will increase.
However, if you add the function to the prototype, the function will
be shared by all the objects, so there will be a save of memory
You can see the difference for yourself by running this code:
var output = function(s) { document.getElementById("output").innerText += s; }
function MyNewClass() {
this.foo = function() {
output("1");
}
}
MyNewClass.prototype.bar = function(){
output("2");
};
var a = new MyNewClass();
a.foo();
a.bar();
a.foo = function() { output("3") };
MyNewClass.prototype.bar = function() { output("4"); };
a.foo();
a.bar();
var b = new MyNewClass();
b.foo();
b.bar();
The output is: 123414
When you change a function as a member variable, you only change that instance. If you change it in the prototype, it affects all instances.
functions of the object should be declared using prototype because prototype is a common space that is shared by all the objects created by the same constructor function and it also saves memory because all objects do not have there own functions created but they all are pointing to one common place.
you can refer it here
https://www.youtube.com/watch?v=fBpPfPjxOhc&list=PLqq-6Pq4lTTaflXUL0v3TSm86nodn0c_u
example
enter code here
//constructor function
function gh(){
this.x=1;
}
//now if you create a object
var p=new gh();
//now i need function show in my object p
function show(){
console.log(x);
}
gh.prototype.show=show();
//it will be added all objects automatically (to understand this study scope chain)
This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 7 years ago.
Which of the following cases is better for performance or proper techniques?
CASE #1
function SomeClass ()
{
this.someVar = null;
this.someFunc = function () {}
}
CASE #2
function SomeClass () {}
SomeClass.prototype.someVar = null;
SomeClass.prototype.someFunc = function () {}
It depends entirely on whether you want them shared between instances created via that constructor function. If you do, put them on the prototype. If you don't, set them up in the constructor.
Beware that putting references to objects/arrays on the prototype is likely to trip you up, as (again) all instances will share those references.
Putting methods (references to functions) on the prototype is fairly standard practice.
Here's an example of getting tripped up by putting an array on the prototype:
function MyConstructor() {
};
MyConstructor.prototype.theArray = []; // Don't do this unless you're really sure
var a = new MyConstructor();
a.theArray.push("foo");
snippet.log(a.theArray.length); // 1 -- so far, everything seems fine
var b = new MyConstructor();
b.theArray.push("bar");
snippet.log(b.theArray.length); // 2 -- huh?!?!
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
The reason, of course, is that both a and b are using the same array: The one on the prototype.
if they are shared among all of the instances of SomeClass, It's better to declare it in the prototype because they will share the same reference which reduces the amount of memory.
but if these properties varies from instance to another, you must declare it in the constructor.
Examples:
function SomeClass () {}
SomeClass.prototype.someVar = null;
SomeClass.prototype.someFunc = function () {}
var a = new SomeClass();
var b = new SomeClass();
a.someFunc === b.someFunc //true because they share the same reference
within constructor:
function SomeClass ()
{
this.someVar = null;
this.someFunc = function () {}
}
var a = new SomeClass();
var b = new SomeClass();
a.someFunc === b.someFunc //false because the now have difference reference
I think the first one will be faster
function SomeClass ()
{
this.someVar = null;
this.someFunc = function () {}
}
because in this case while accessing someClassInstace.someFunc javascript will not look up in prototype for someFunc function.
This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 9 years ago.
So, I am not a JavaScript expert, just trying to understand what the difference is between two following snippets of code. I have a project that I want to convert to TypeScript and I need to understand the difference between two code snippets being generated.
var Pony = (function () {
function Pony() { }
Pony.prototype.bite = function () {
alert("Chomp!");
};
return Pony;
})();
var Pony2 = (function () {
function Pony2() {
var self = this;
self.bite = function () {
alert("Chomp!");
};
}
return Pony2;
})();
The difference between the two is that you can get to the prototype of the first Pony via attributes on the object stored in var Pony and could expand upon or use the associated bits of that prototype elsewhere where as Pony2 would just be considered a function. So if you do not plan on using any sort of prototypical inheritance later on they are equivalent.
The answers above give a good overview on the difference between putting on the prototype and putting on the instance. As to your question about converting to TypeScript, below is how you would write them both:
class Pony {
bite(){
alert('chomp');
}
}
class Pony2 {
bite: () => void;
constructor(){
this.bite = () => alert('chomp');
}
}
As far as how you use them, there's no difference. However, from a performance standpoint the former method would be preferable. Let's extend your example a little bit:
var prototypePony1 = new Pony();
var prototypePony2 = new Pony();
var thisPony1 = new Pony2();
var thisPony2 = new Pony2();
prototypePony1.hasOwnProperty('bite'); //returns false
prototypePony2.hasOwnProperty('bite'); //returns false
thisPony1.hasOwnProperty('bite'); //returns true
thisPony2.hasOwnProperty('bite'); //returns true
Pony.prototype.bite = function() { alert('Nomnomnom!'); };
Pony2.prototype.bite = function() { alert('Nomnomnom!'); };
prototypePony1.bite(); //alerts 'Nomnomnom!'
prototypePony2.bite(); //alerts 'Nomnomnom!'
thisPony1.bite(); //alerts 'Chomp!', instance property is accessed first
delete thisPony2.bite;
thisPony2.hasOwnProperty('bite'); //returns false
thisPony2.bite(); //alerts 'Nomnomnom!'
In the example above, thisPony1 and thisPony2 both get their own copy of the bite function, since it was defined using this However, prototypePony1 and prototypePony2 both share the same copy of bite from Pony's constructor.
Once we define the bite prototype on Pony2, the instance property is still accessed first on thisPony1. It's not until we delete the instance property that we see the newly defined prototype property on thisPony2.
For more detailed info on defining object methods, have a look here.
This question already has answers here:
this.constructor.prototype -- can't wholly overwrite, but can write individual props?
(2 answers)
Closed 6 years ago.
If I declare the base prototype object outside the constructor for an object, all created objects are based on that single base object which is not suitable for my needs because I need more than one instance of the base object.
In short: Is this code correct? It works but I'm picky about having correct code.
Example:
function BaseObject()
{
BaseObject.prototype.insertObject = function()…
…
… // Some other functions.
}
function Object1()
{
Object1.prototype = new BaseObject();
Object1.prototype.coolFunction = function()…
…
… // Same kind of pattern.
}
function Object2()
{
Object2.prototype = new Object1();
Object2.prototype.incredibleFunction = function()…
…
… // You get the idea.
}
The general pattern:
function Base ( baseMember ) {
this.baseMember = baseMember;
}
Base.prototype.baseFunc = function () {};
function Derived ( baseMember, derivedMember ) {
Base.apply( this, arguments );
this.derivedMember = derivedMember;
}
Derived.prototype = Object.create( Base.prototype );
Derived.prototype.constructor = Derived;
Derived.prototype.derivedFunc = function () {};
It's ugly, I know...
No, all the code that is currently inside your constructor functions should be outside of them. Right now you are reassigning those properties of the prototype every time someone creates a new object.
Finally, points of good-practice:
You should always "fix" the constructor property of any derived prototypes. This is a quirk of JS inheritance; it gets overwritten. People rarely depend on the constructor property being correct, but sometimes they do, and it just feels wrong if you don't.
Object.create(Base.prototype) is better than new Base() if you are working in browsers that support it, or using es5-shim. It only instantiates the object, instead of creating it, which is good since you don't need an actual copy of the object to perform prototypal inheritance.
This would all look like:
function BaseObject() { }
BaseObject.prototype.insertObject = function () { };
function Object1() { }
Object1.prototype = Object.create(BaseObject.prototype);
Object1.prototype.constructor = Object1;
Object1.prototype.coolFunction = function () { };
function Object2() { }
Object2.prototype = Object.create(Object1.prototype);
Object2.prototype.constructor = Object2;
Object2.prototype.incredibleFunction = function () { };
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Get property of object in JavaScript
var Terminal = function() {
this.walk = function() {
alert('hello');
}
this.go = 'walk';
this.move = 'walk';
}
var term = new Terminal();
var fn = 'walk';
if (term.hasOwnProperty(fn)) {
term.{fn};
}
How can I run the method term.walk() using the string 'walk'?
There are a couple of ways. The simplest is
term[fn]();
Or alternatively
var funcObj = term[fn];
funcObj.apply(term);
Use term[fn] to access the <fn> property of term.
All properties can be accessed using object["propertyname"]. Globally defined properties/methods can be called through window["propertyname"].
There's only one occasion where variables cannot be accessed through obj["prop_name"]:
function foo(){
var bar = 759;
//There is no "obj" where obj.bar exists.
}