Constructor function - javascript

What is the difference between these two codes?
let user = new function() {
this.name = "John";
this.isAdmin = false;
}
vs
let user = {
name: "John",
isAdmin: false
}

The only difference is that the first user, created via new, has an internal prototype of a (nearly) empty object, and that empty object inherits from Object.prototype:
instance <- (empty object) <- Object.prototype
let user = new function() {
this.name = "John";
this.isAdmin = false;
};
console.log(user);
Technically, the object isn't entirely empty, it has a non-enumerable constructor property pointing to the function
This nearly empty object is the .prototype property of the function - but since that prototype object doesn't have any properties on it, it looks empty. If you had put properties on the function's .prototype object, these would be visible on the intermediate object:
function Foo() {
this.name = "John";
this.isAdmin = false;
}
Foo.prototype.prop = 'val';
let user = new Foo();
console.log(user);
console.log(Object.getPrototypeOf(user).hasOwnProperty('prop'));
console.log(Object.getPrototypeOf(user) === Foo.prototype);
The user from an object literal, on the other hand, inherits directly from Object.prototype:
instance <- Object.prototype
let user = {
name: "John",
isAdmin: false
}
console.log(Object.getPrototypeOf(user) === Object.prototype);

Firstly both of them create a new object and the following code inside them is assigned to the object.
They then execute the code in the function body and can return the value.

Related

Javascript Prototype object and Inheritance [duplicate]

I recently stumbled upon the Object.create() method in JavaScript, and am trying to deduce how it is different from creating a new instance of an object with new SomeFunction(), and when you would want to use one over the other.
Consider the following example:
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2
Notice that the same behaviour is observed in both cases. It seems to me that the primary differences between these two scenarios are:
The object used in Object.create() actually forms the prototype of the new object, whereas in the new Function() from the declared properties/functions do not form the prototype.
You cannot create closures with the Object.create() syntax as you would with the functional syntax. This is logical given the lexical (vs block) type scope of JavaScript.
Are the above statements correct? And am I missing something? When would you use one over the other?
EDIT: link to jsfiddle version of above code sample: http://jsfiddle.net/rZfYL/
Very simply said, new X is Object.create(X.prototype) with additionally running the constructor function. (And giving the constructor the chance to return the actual object that should be the result of the expression instead of this.)
That’s it. :)
The rest of the answers are just confusing, because apparently nobody else reads the definition of new either. ;)
The object used in Object.create actually forms the prototype of the new object, where as in the new Function() form the declared properties/functions do not form the prototype.
Yes, Object.create builds an object that inherits directly from the one passed as its first argument.
With constructor functions, the newly created object inherits from the constructor's prototype, e.g.:
var o = new SomeConstructor();
In the above example, o inherits directly from SomeConstructor.prototype.
There's a difference here, with Object.create you can create an object that doesn't inherit from anything, Object.create(null);, on the other hand, if you set SomeConstructor.prototype = null; the newly created object will inherit from Object.prototype.
You cannot create closures with the Object.create syntax as you would with the functional syntax. This is logical given the lexical (vs block) type scope of JavaScript.
Well, you can create closures, e.g. using property descriptors argument:
var o = Object.create({inherited: 1}, {
foo: {
get: (function () { // a closure
var closured = 'foo';
return function () {
return closured+'bar';
};
})()
}
});
o.foo; // "foobar"
Note that I'm talking about the ECMAScript 5th Edition Object.create method, not the Crockford's shim.
The method is starting to be natively implemented on latest browsers, check this compatibility table.
Here are the steps that happen internally for both calls:
(Hint: the only difference is in step 3)
new Test():
create new Object() obj
set obj.__proto__ to Test.prototype
return Test.call(obj) || obj;
// normally obj is returned but constructors in JS can return a value
Object.create( Test.prototype )
create new Object() obj
set obj.__proto__ to Test.prototype
return obj;
So basically Object.create doesn't execute the constructor.
Let me try to explain (more on Blog) :
When you write Car constructor var Car = function(){}, this is how things are internally:
We have one {prototype} hidden link to Function.prototype which is not accessible and one prototype link to Car.prototype which is accessible and has an actual constructor of Car. Both Function.prototype and Car.prototype have hidden links to Object.prototype.
When we want to create two equivalent objects by using the new operator and create method then we have to do it like this: Honda = new Car(); and Maruti = Object.create(Car.prototype).
What is happening?
Honda = new Car(); — When you create an object like this then hidden {prototype} property is pointed to Car.prototype. So here, the {prototype} of the Honda object will always be Car.prototype — we don't have any option to change the {prototype} property of the object. What if I want to change the prototype of our newly created object?
Maruti = Object.create(Car.prototype) — When you create an object like this you have an extra option to choose your object's {prototype} property. If you want Car.prototype as the {prototype} then pass it as a parameter in the function. If you don't want any {prototype} for your object then you can pass null like this: Maruti = Object.create(null).
Conclusion — By using the method Object.create you have the freedom to choose your object {prototype} property. In new Car();, you don't have that freedom.
Preferred way in OO JavaScript :
Suppose we have two objects a and b.
var a = new Object();
var b = new Object();
Now, suppose a has some methods which b also wants to access. For that, we require object inheritance (a should be the prototype of b only if we want access to those methods). If we check the prototypes of a and b then we will find out that they share the prototype Object.prototype.
Object.prototype.isPrototypeOf(b); //true
a.isPrototypeOf(b); //false (the problem comes into the picture here).
Problem — we want object a as the prototype of b, but here we created object b with the prototype Object.prototype.
Solution — ECMAScript 5 introduced Object.create(), to achieve such inheritance easily. If we create object b like this:
var b = Object.create(a);
then,
a.isPrototypeOf(b);// true (problem solved, you included object a in the prototype chain of object b.)
So, if you are doing object oriented scripting then Object.create() is very useful for inheritance.
This:
var foo = new Foo();
and
var foo = Object.create(Foo.prototype);
are quite similar. One important difference is that new Foo actually runs constructor code, whereas Object.create will not execute code such as
function Foo() {
alert("This constructor does not run with Object.create");
}
Note that if you use the two-parameter version of Object.create() then you can do much more powerful things.
The difference is the so-called "pseudoclassical vs. prototypal inheritance". The suggestion is to use only one type in your code, not mixing the two.
In pseudoclassical inheritance (with "new" operator), imagine that you first define a pseudo-class, and then create objects from that class. For example, define a pseudo-class "Person", and then create "Alice" and "Bob" from "Person".
In prototypal inheritance (using Object.create), you directly create a specific person "Alice", and then create another person "Bob" using "Alice" as a prototype. There is no "class" here; all are objects.
Internally, JavaScript uses "prototypal inheritance"; the "pseudoclassical" way is just some sugar.
See this link for a comparison of the two ways.
function Test(){
this.prop1 = 'prop1';
this.prop2 = 'prop2';
this.func1 = function(){
return this.prop1 + this.prop2;
}
};
Test.prototype.protoProp1 = 'protoProp1';
Test.prototype.protoProp2 = 'protoProp2';
var newKeywordTest = new Test();
var objectCreateTest = Object.create(Test.prototype);
/* Object.create */
console.log(objectCreateTest.prop1); // undefined
console.log(objectCreateTest.protoProp1); // protoProp1
console.log(objectCreateTest.__proto__.protoProp1); // protoProp1
/* new */
console.log(newKeywordTest.prop1); // prop1
console.log(newKeywordTest.__proto__.protoProp1); // protoProp1
Summary:
1) with new keyword there are two things to note;
a) function is used as a constructor
b) function.prototype object is passed to the __proto__ property ... or where __proto__ is not supported, it is the second place where the new object looks to find properties
2) with Object.create(obj.prototype) you are constructing an object (obj.prototype) and passing it to the intended object ..with the difference that now new object's __proto__ is also pointing to obj.prototype (please ref ans by xj9 for that)
Object creation variants.
Variant 1 : 'new Object()' -> Object constructor without arguments.
var p1 = new Object(); // 'new Object()' create and return empty object -> {}
var p2 = new Object(); // 'new Object()' create and return empty object -> {}
console.log(p1); // empty object -> {}
console.log(p2); // empty object -> {}
// p1 and p2 are pointers to different objects
console.log(p1 === p2); // false
console.log(p1.prototype); // undefined
// empty object which is in fact Object.prototype
console.log(p1.__proto__); // {}
// empty object to which p1.__proto__ points
console.log(Object.prototype); // {}
console.log(p1.__proto__ === Object.prototype); // true
// null, which is in fact Object.prototype.__proto__
console.log(p1.__proto__.__proto__); // null
console.log(Object.prototype.__proto__); // null
Variant 2 : 'new Object(person)' -> Object constructor with argument.
const person = {
name: 'no name',
lastName: 'no lastName',
age: -1
}
// 'new Object(person)' return 'person', which is pointer to the object ->
// -> { name: 'no name', lastName: 'no lastName', age: -1 }
var p1 = new Object(person);
// 'new Object(person)' return 'person', which is pointer to the object ->
// -> { name: 'no name', lastName: 'no lastName', age: -1 }
var p2 = new Object(person);
// person, p1 and p2 are pointers to the same object
console.log(p1 === p2); // true
console.log(p1 === person); // true
console.log(p2 === person); // true
p1.name = 'John'; // change 'name' by 'p1'
p2.lastName = 'Doe'; // change 'lastName' by 'p2'
person.age = 25; // change 'age' by 'person'
// when print 'p1', 'p2' and 'person', it's the same result,
// because the object they points is the same
console.log(p1); // { name: 'John', lastName: 'Doe', age: 25 }
console.log(p2); // { name: 'John', lastName: 'Doe', age: 25 }
console.log(person); // { name: 'John', lastName: 'Doe', age: 25 }
Variant 3.1 : 'Object.create(person)'. Use Object.create with simple object 'person'. 'Object.create(person)' will create(and return) new empty object and add property '__proto__' to the same new empty object. This property '__proto__' will point to the object 'person'.
const person = {
name: 'no name',
lastName: 'no lastName',
age: -1,
getInfo: function getName() {
return `${this.name} ${this.lastName}, ${this.age}!`;
}
}
var p1 = Object.create(person);
var p2 = Object.create(person);
// 'p1.__proto__' and 'p2.__proto__' points to
// the same object -> 'person'
// { name: 'no name', lastName: 'no lastName', age: -1, getInfo: [Function: getName] }
console.log(p1.__proto__);
console.log(p2.__proto__);
console.log(p1.__proto__ === p2.__proto__); // true
console.log(person.__proto__); // {}(which is the Object.prototype)
// 'person', 'p1' and 'p2' are different
console.log(p1 === person); // false
console.log(p1 === p2); // false
console.log(p2 === person); // false
// { name: 'no name', lastName: 'no lastName', age: -1, getInfo: [Function: getName] }
console.log(person);
console.log(p1); // empty object - {}
console.log(p2); // empty object - {}
// add properties to object 'p1'
// (properties with the same names like in object 'person')
p1.name = 'John';
p1.lastName = 'Doe';
p1.age = 25;
// add properties to object 'p2'
// (properties with the same names like in object 'person')
p2.name = 'Tom';
p2.lastName = 'Harrison';
p2.age = 38;
// { name: 'no name', lastName: 'no lastName', age: -1, getInfo: [Function: getName] }
console.log(person);
// { name: 'John', lastName: 'Doe', age: 25 }
console.log(p1);
// { name: 'Tom', lastName: 'Harrison', age: 38 }
console.log(p2);
// use by '__proto__'(link from 'p1' to 'person'),
// person's function 'getInfo'
console.log(p1.getInfo()); // John Doe, 25!
// use by '__proto__'(link from 'p2' to 'person'),
// person's function 'getInfo'
console.log(p2.getInfo()); // Tom Harrison, 38!
Variant 3.2 : 'Object.create(Object.prototype)'. Use Object.create with built-in object -> 'Object.prototype'. 'Object.create(Object.prototype)' will create(and return) new empty object and add property '__proto__' to the same new empty object. This property '__proto__' will point to the object 'Object.prototype'.
// 'Object.create(Object.prototype)' :
// 1. create and return empty object -> {}.
// 2. add to 'p1' property '__proto__', which is link to 'Object.prototype'
var p1 = Object.create(Object.prototype);
// 'Object.create(Object.prototype)' :
// 1. create and return empty object -> {}.
// 2. add to 'p2' property '__proto__', which is link to 'Object.prototype'
var p2 = Object.create(Object.prototype);
console.log(p1); // {}
console.log(p2); // {}
console.log(p1 === p2); // false
console.log(p1.prototype); // undefined
console.log(p2.prototype); // undefined
console.log(p1.__proto__ === Object.prototype); // true
console.log(p2.__proto__ === Object.prototype); // true
Variant 4 : 'new SomeFunction()'
// 'this' in constructor-function 'Person'
// represents a new instace,
// that will be created by 'new Person(...)'
// and returned implicitly
function Person(name, lastName, age) {
this.name = name;
this.lastName = lastName;
this.age = age;
//-----------------------------------------------------------------
// !--- only for demonstration ---
// if add function 'getInfo' into
// constructor-function 'Person',
// then all instances will have a copy of the function 'getInfo'!
//
// this.getInfo: function getInfo() {
// return this.name + " " + this.lastName + ", " + this.age + "!";
// }
//-----------------------------------------------------------------
}
// 'Person.prototype' is an empty object
// (before add function 'getInfo')
console.log(Person.prototype); // Person {}
// With 'getInfo' added to 'Person.prototype',
// instances by their properties '__proto__',
// will have access to the function 'getInfo'.
// With this approach, instances not need
// a copy of the function 'getInfo' for every instance.
Person.prototype.getInfo = function getInfo() {
return this.name + " " + this.lastName + ", " + this.age + "!";
}
// after function 'getInfo' is added to 'Person.prototype'
console.log(Person.prototype); // Person { getInfo: [Function: getInfo] }
// create instance 'p1'
var p1 = new Person('John', 'Doe', 25);
// create instance 'p2'
var p2 = new Person('Tom', 'Harrison', 38);
// Person { name: 'John', lastName: 'Doe', age: 25 }
console.log(p1);
// Person { name: 'Tom', lastName: 'Harrison', age: 38 }
console.log(p2);
// 'p1.__proto__' points to 'Person.prototype'
console.log(p1.__proto__); // Person { getInfo: [Function: getInfo] }
// 'p2.__proto__' points to 'Person.prototype'
console.log(p2.__proto__); // Person { getInfo: [Function: getInfo] }
console.log(p1.__proto__ === p2.__proto__); // true
// 'p1' and 'p2' points to different objects(instaces of 'Person')
console.log(p1 === p2); // false
// 'p1' by its property '__proto__' reaches 'Person.prototype.getInfo'
// and use 'getInfo' with 'p1'-instance's data
console.log(p1.getInfo()); // John Doe, 25!
// 'p2' by its property '__proto__' reaches 'Person.prototype.getInfo'
// and use 'getInfo' with 'p2'-instance's data
console.log(p2.getInfo()); // Tom Harrison, 38!
Accordingly to this answer and to this video new keyword does next things:
Creates new object.
Links new object to constructor function (prototype).
Makes this variable point to the new object.
Executes constructor function using the new object and implicit perform return this;
Assigns constructor function name to new object's property constructor.
Object.create performs only 1st and 2nd steps!!!
Internally Object.create does this:
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
The syntax just takes away the illusion that JavaScript uses Classical Inheritance.
Object.create(Constructor.prototype) is the part of new Constructor
this is new Constructor implementation
// 1. define constructor function
function myConstructor(name, age) {
this.name = name;
this.age = age;
}
myConstructor.prototype.greet = function(){
console.log(this.name, this.age)
};
// 2. new operator implementation
let newOperatorWithConstructor = function(name, age) {
const newInstance = new Object(); // empty object
Object.setPrototypeOf(newInstance, myConstructor.prototype); // set prototype
const bindedConstructor = myConstructor.bind(newInstance); // this binding
bindedConstructor(name, age); // execute binded constructor function
return newInstance; // return instance
};
// 3. produce new instance
const instance = new myConstructor("jun", 28);
const instance2 = newOperatorWithConstructor("jun", 28);
console.log(instance);
console.log(instance2);
new Constructor implementation contains Object.create method
newOperatorWithConstructor = function(name, age) {
const newInstance = Object.create(myConstructor.prototype); // empty object, prototype chaining
const bindedConstructor = myConstructor.bind(newInstance); // this binding
bindedConstructor(name, age); // execute binded constructor function
return newInstance; // return instance
};
console.log(newOperatorWithConstructor("jun", 28));

Are properties defined in constructor function own or inherited?

I am new to Javascript sorry if this sounds as an easy question.
If I have following constructor function:
function Person(x,y){
this.name = x;
this.surname = y;
}
I am curious whether properties name and surname are considered own properties of objects of type Person or inherited?
e.g.
var x = new Person("John", "Doe");
I did some tests using hasOwnProperty which suggest they are considered own properties rather than inherited, just wanted to verify.
Yes, they are own properties. When instantiating an object with new Person, an object will be created, your function Person will be called, and this inside Person refers to this new object. You're then explicitly directly setting properties on this object. In essence, no different than this:
function person(obj) {
obj.name = 'Foo';
obj.surname = 'Bar';
}
var o = {};
person(o);
o.name // Foo
The easiest way for you to check this is to just try it and see.
But yes, they are considered own properties. Inside the constructor function, this is a reference to the newly constructed object (when Person is called with new).
It's essentially the same thing as doing
var x = {};
x.name = 'foo'
console.log(x.hasOwnProperty('name')); // true
Compare that to a prototype property:
function Person(name) {
this.name = name;
}
Person.prototype.brain = 'meat-like';
var p = new Person('Bob');
console.log(p.name); // Bob
console.log(p.brain); // meat-like
console.log(p.hasOwnProperty('name')); // true
console.log(p.hasOwnProperty('brain')); // false

Why isn't my object private when my variable is?

I'm trying to make a object private, but not sure how to do that. As you can see the name variable is private, I can't edit it but when it comes to the object that I return, I can edit. I dont want that to be possible, though.
I quite new to object-oriented and private methods in javascript, so could someone tell me what's right and wrong here. :) How can I solve this?
Thanks!
var User = function() {
var name = 'bob';
this.getName = function() {
return name;
}
var otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return otherInfo;
}
}
var person = new User();
var name = person.getName();
name = 'jenny';
console.log(person.getName()); // bob
var other = person.getOther();
other.age = 'wtf?';
console.log(person.getOther()); // { age: 'wtf?', human: true }
Primitive values such as Strings are passed by value. This means when you assign a String to your variable, you are setting the actual value of the String to the variable.
Objects are passed by reference. This means when you assign an Object to your variable, you are simply making a reference to the Object, not it's actual value. If you had one Object and assigned it to 6 different variables, each variable would have a reference to the same underlying Object.
In your example, your getOther method is returning a reference to the otherInfo object. So when you set the age property to "wtf", you are setting it on the Object that your variable refers to.
You also declare var name twice.
When you var person = new User(); a var name is declared within the scope of the User function.
When you var name = person.getName(); you are declaring a variable with the same name outside the scope of the User function.
So, when you name = 'Jenny'; the interpreter associates this string the name variable outside the scope of User.
In general, it is a bad idea to use such variables with common names (name, title, id, ...) as global variables. I would refer to the object attributes with this. and define setters as well as getters. You can also ignore the setters and refer to the User attributes with person., like this:
function User() {
this.name = 'bob';
this.getName = function() {
return this.name;
}
this.otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return this.otherInfo;
}
}
var person = new User();
console.log(person.getName()); // bob
person.name = 'jenny';
console.log(person.getName()); // jenny
console.log(person.getOther(); // { age: 20, human: true }
person.otherInfo.age = 'wtf?';
console.log(person.getOther()); // { age: 'wtf?', human: true }
You don't have “private” things in object scope in Javascript. The only way to hide things from the outside is with a function scope, like you did with name (a local variable in the function User).
To return an object with the same content every time, you could make the object inside the function. Like this, for instance:
this.getOther = function() {
var otherInfo = {
age: 20,
human: true,
}
return otherInfo;
}
Or just:
this.getOther = function() {
return {
age: 20,
human: true,
};
}
In both cases, you will be creating a new object with every call.
It is happen, because in JS object passes by link - there are not coped from source object.
Just try copy object:
var User = function() {
var name = 'bob';
this.getName = function() {
return name;
}
var otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return Object.assign({}, otherInfo);
}
}
var person = new User();
var name = person.getName();
name = 'jenny';
console.log(person.getName()); // bob
var other = person.getOther();
other.age = 'wtf?';
console.log(person.getOther()); // { age: 20, human: true }

How does function scope work in JavaScript?

I am having some trouble understanding function scope in JavaScript:
function Person() {
var _firstName;
var _lastName;
}
personOne = new Person();
personOne._firstName = "Fred";
alert(personOne._firstName);
This outputs "Fred", but I thought the variables of the Person function would only be accessible inside the function. Why does it work?
In JavaScript, objects are dynamically-expandable.
For example:
var obj = {};
obj.firstName = "Matías"; // <-- This adds the property even if it doesn't exist
In the other hand, if you want to declare properties that should be part of the object in the constructor function you need to qualify them with this:
function Person() {
this._firstName = null;
this._lastName = null;
}
Extra info
If you want to avoid objects from being dynamically-expandable, you can use the ECMA-Script 5 Object.preventExtensions function:
var obj = {};
Object.preventExtensions(obj);
// This property won't be added!
obj.text = "hello world";
Because in the line:
personOne._firstName = "Fred";
You assigned a new property to the object with a value of "Fred". It has nothing to do with the (internally-scoped) variable you declared inside the function.
And in the following line, you're actually alerting the value of the newly-created property and not the variable.
See MDN
It works because you create the property _firstName for the object Person.
personOne._firstName = "Fred"; // here you create the property
In the example below I highlighted the fact that _firstName is innacesible.
function Person() {
var _firstName= "Fred";;
var _lastName;
}
personOne = new Person();
alert(personOne._firstName); // output: "undefined"
If you want to make them accesible you can make use of this to add a new property to the object.
function Person() {
var self = this;
self._firstName= "Fred";
var _lastName;
return self;
}
var personOne = new Person();
alert(personOne._firstName); // output: "Fred"
In this line:
personOne._firstName = "Fred";
you are actually creating the property _firstName of the object. it is not the same as the var you created in the constructor function. You can always add new properties to a JavaScript object. Each property of an object is accessible. There is no such thing as a private property.
Due to function scope you will not be able to change the variables inside Person() from outside if you do not make methods available in Person to set the values of those variables.
function Person(firstName, lastName) {
var _firstName = firstName, _lastName = lastname;
this.getFullName = function () {
return _firstName + " " + _lastName;
};
}
var someone = new Person("Some", "one");
someone._firstName = "something else"; // creates new property in the object someone
var fullName = someone.getFullName(); // still returns "some one"
You cannot reference _firstName inside the object declaration. If you want to access the object property you need to declare with this, otherwise the _firstName or _lastName are considered local variables.
So to access the _firstName or _lastName as object properties, you have to declare as in the following way:
function Person() {
this._firstName = "John";
this._lastName = "Doe";
}
You may access _firstName and _lastName after you instantiate the Person.
personOne = new Person();
personOne._firstName = "Fred";
This way you will override the properties already defined in the object constructor. In your case because _firstName is declared inside the Object definition the scope of that variable is bind locally to that object. But when you instantiate the object you assign a new property which extends the originally declared object.
The most widely accepted pattern is to bind the object properties on the object declaration, but declare the object methods on their prototype level.
Like so:
function Person() {
this._firstName;
//...
}
Person.prototype = function() {
getName : function() {
//...
},
setName : function(name) {
this._firstName = name;
}
}
JS objects objects are "expandable", you can add properties dinamically.
function Person() {
var _firstName;
var _lastName;
}
var personOne = new Person();
console.log(personOne); // Person {}
personOne._firstName = "Fred";
personOne._age = 20;
console.log(personOne); // Person {_firstName: "Fred", _age: 20}
You don't actually have access to the _firstName created inside the function scope, but rather you create a property with that name on your newly created object.
In order to expose a property, you attach it using this keyword (which is a reference to the newly created object).
function Person() {
console.log(this); // Person {}
this._firstName = "Sam";
console.log(this); // Person {_firstName: "Sam"}
}

When should you use "prototype" during object augmentation in javascript?

I'm confused about the notion of "prototype" in javascript.
When I'm defining an object both of the following seem to work:
myObject = {};
myObject.prototype.method1 = function() { ... };
myObject.prototype.method2 = function() { ... };
myObject.prototype.method3 = function() { ... };
and...
myObject = {};
myObject.method1 = function() { ... };
myObject.method2 = function() { ... };
myObject.method3 = function() { ... };
Could anyone shed some light on this? What exactly is the difference between these two ways of creating an object and why would I choose one over the other? (I have this feeling in my gut it's important...)
Thanks!
You should use the prototype property only on Constructor Functions, not in object instances, for example:
function Test () {}
Test.prototype.method1 = function () {/*...*/};
var obj = new Test();
The prototype property of constructor functions, is used by the new operator, when it creates our new object instance.
All native objects have a hidden link, that builds up the prototype chain.
This hidden link between objects is the [[Prototype]] internal property, and the new operator is the only one that can set it.
In the above example, the obj is associated internally with it's constructor prototype, the method1 is accessible from obj, but it doesn't exists physically on this object, that method exists on the Test.prototype object, and it's retrieved through the prototype chain, e.g.:
typeof obj.method1; // "function"
obj.hasOwnProperty('method1'); // false
obj.method1 === Test.prototype.method1; // true
On object instances, assigning a prototype property is meaningless, it will be taken just as any other property name:
var myObject = {};
myObject.prototype = "foo";
myObject.bar = "bar";
// myObject is simply {"prototype":"foo","bar":"bar"}
Second way adds methods only to this object. First way makes it available for other objects created with new with this "type".

Categories