Upload
vernon-kesner
View
40
Download
1
Embed Size (px)
Citation preview
Every object in JavaScript links to a prototype object
console.log( “”.__proto__ === String.prototype ); // true!
That, if you’re wondering, is pronounced “dunder proto"
Constructor Functions
• Constructor functions are used to create new objects.
• Very useful when creating multiple instances of a particular object
var list = new Array( 1, 2, 3 );
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
var list = new Array( 1, 2, 3 );
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
Where did that push method come from?
var list = new Array( 1, 2, 3 );
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
Where did that push method come from?
It’s inherited from Array.prototype!
var list = new Array( 1, 2,
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
new Array( 1, 2, 3 )
A function is a block of code that is defined once but can be invoked any number of times.
var list = new Array( 1, 2,
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
new Array( 1, 2, 3 )
Each function has a special thiskeyword, the functions invocation context
var list = new Array( 1, 2,
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
new Array( 1, 2, 3 )
Functions used to initialize a new object are called Constructor Functions
var list = new Array( 1, 2,
list.push( 4 );
// list === [ 1, 2, 3, 4 ]
new Array( 1, 2, 3 )
All functions - because they are objects - havea prototype property that is a link to the prototype object
So let’s look at an example
function Person ( name ) {this.name = name;
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = new Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
Constructor Functions
function Person ( name ) {this.name = name;
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = new Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
• Common convention is to uppercase the first character of the function name of a constructor function
• The context of this within the constructor function is the newly created object
• No return statement required
Constructor Functions
function Person ( name ) {this.name = name;
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = new Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
• We can add custom functionality to the prototype object of our function
• This added functionality is inherited by each instance of our constructor we create
• The context of methods added to the prototype object are the created instance itself
Constructor Functions
function Person ( name ) {this.name = name;
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = new Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
• A new object instance is created by invoking a constructor function with the new operator
• Here, we create vernon and assign is the specified values as its properties
• So, the value of vernon.name would be “Vernon”
• We can now create as many “Person’s” as we want, and they will all be able to sayHi!
Constructor Functions
function Person ( name ) {this.name = name; // this === window
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
• Invoking a constructor function without the new operator has unintended side effects
• The context of the newly created object in the case of a missing new, is window
Constructor Functions
function Person ( name ) {if ( !( this instanceof Person ) ) {
return new Person( name );} this.name = name;
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = new Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
• We can protect ourselves from these side effects by using the instanceof operator
• instanceof tests whether an object has the prototype property of a constructor in its prototype chain
• Here, we test the context of our constructor and return the proper invocation if needed
function Person ( name ) {this.name = name;
}
Person.prototype.sayHi = function () {console.log( “Hi! I’m “, this.name );
}
var vernon = new Person( “Vernon” );
vernon.sayHi(); // Hi! I’m Vernon
Person.prototype.sayBye = function () {console.log( “Bye!” );
}
vernon.sayBye(); // Bye!
function Person ( name ) {this.name = name;
}
Person.prototype.sayHi = function () {console.log(
}
var vernon = new Person(
vernon.sayHi(); // Hi! I’m Vernon
Personconsole
}
vernon
Prototypal Inheritance
Prototypal Inheritance
• All inheritance in JavaScript is through the prototype object
• Object.prototype does not inherit any properties
• All built-in constructors inherit from Object.prototype
• Best understood by looking at an example
http://bit.ly/1MNdeGU
Creates a new object with the specified prototype object and properties
Prototypal Inheritance | Object.create()
var obj = {}; // Inherits from Object.prototypeobj.foo = "bar"; // has an own property of foo
var obj2 = Object.create( obj ); // Inherits from obj and Object.prototypeobj2.bar = "baz"; // has an own property of bar
var obj3 = Object.create( obj2 ); // Inherits from obj, obj2 and Object.prototypeobj3.baz = "thud"; // has an own property of baz
console.log( obj3.foo ); // barconsole.log( obj3.bar ); // bazconsole.log( obj3.hasOwnProperty( “foo” ) ); // false
var obj = {}; // Inherits from Object.prototypeobj.foo = "bar"; // has an own property of foo
var obj2 = Object.createobj2.bar = "baz"; // has an own property of bar
var obj3 = Object.createobj3.baz = "thud"; // has an own property of baz
console.log( obj3.foo ); // barconsole.log( obj3.bar ); // bazconsole.log( obj3.hasOwnProperty(
This inheritance lookup is done against the prototype chain
Prototypal Inheritance
var obj = {}; // Inherits from Object.prototypeobj.foo = "bar"; // has an own property of foo
var obj2 = Object.createobj2.bar = "baz"; // has an own property of bar
var obj3 = Object.createobj3.baz = "thud"; // has an own property of baz
console.log( obj3.foo ); // barconsole.log( obj3.bar ); // bazconsole.log( obj3.hasOwnProperty(
We can leverage this to create scalable objects
Prototypal Inheritance
var obj = {}; // Inherits from Object.prototypeobj.foo = "bar"; // has an own property of foo
var obj2 = Object.createobj2.bar = "baz"; // has an own property of bar
var obj3 = Object.createobj3.baz = "thud"; // has an own property of baz
console.log( obj3.foo ); // barconsole.log( obj3.bar ); // bazconsole.log( obj3.hasOwnProperty(
Let’s look at another example
Prototypal Inheritance
var User = function( details ) { details = details || {}; this.firstname = details.firstname; this.lastname = details.lastname;
};
Let’s create a User constructor function
var User = function( details ) { details = details || {}; this.firstname = details.firstname; this.lastname = details.lastname;
};
User.prototype.logName = function() {console.log( this.firstname + " " + this.lastname );
};
Now, we’ll add a logName method to the prototype
var User = function( details ) { details = details || {}; this.firstname = details.firstname; this.lastname = details.lastname;
};
User.prototype.logName = function() {console.log( this.firstname + " " + this.lastname );
};
var john = new User( { firstname: "John", lastname: "Doe" } );
Finally, let’s create an instance of a User
var User = function( details ) { … };
User.prototype.logName = function() { … };
var john = new User( { firstname: "John", lastname: "Doe" } );
var Admin = function( details ) { this.firstname = details.firstname; this.lastname = details.lastname; this.fullaccess = true;};
Now, let’s add an Admin constructor function
var User = function( details ) { … };
User.prototype.logName = function() { … };
var john = new User( { firstname: "John", lastname: "Doe" } );
var Admin = function( details ) { this.firstname = details.firstname; this.lastname = details.lastname; this.fullaccess = true;};
Admin.prototype = new User();Admin.prototype.constructor = Admin;
We can inherit functionality from our User function
var User = function( details ) { … };
User.prototype.logName = function() { … };
var john = new User( { firstname: "John", lastname: "Doe" } );
var Admin = function( details ) { this.firstname = details.firstname; this.lastname = details.lastname; this.fullaccess = true;};
Admin.prototype = new User();Admin.prototype.constructor = Admin;
var jane = new Admin( { firstname: "Jane", lastname: "Doe" } );
jane.logName(); // Jane Doe
Our new Admin instance has access to logName
Inheritance and the prototype chain
• ECMAScript 6 introduces a new set of keywords implementing “classes” in JavaScript. It’s important to note that these classes are still prototype based.
• Object.create is another method of inheritance
• Do not extend native prototypes unless you are back porting newer features of JavaScript to older engines
http://bit.ly/1MNdeGU