ObjectOrientedJavaScript

advertisement
Object Oriented JavaScript
JavaScript
• Really only 4 types in JavaScript
– number, string, boolean
– Object (includes arrays)
• Remember that an object is really just a bunch of
key-value pairs
• Ways to create an object
– Object literal: var obj = {};
– Create a new blank object: var obj = new Object();
– Write a constructor function: var pt = new Point(3,4);
Constructor functions
• Normal JavaScript function
• Called with new like Java: var pt = new Point(3, 4);
• Generally sets some properties and methods using
“this”
// Constructs and returns a new Point object.
function Point(xValue, yValue) {
this.x = xValue;
this.y = yValue;
this.distanceFromOrigin = function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
};
}
• By convention, constructors start with uppercase
letters
• Called with new
Prototypes
• every object contains a reference to a prototype object
• a prototype can have a prototype, and so on
– an object "inherits" all methods/data from its prototype(s)
– doesn't have to make a copy of them; saves memory
– prototypes allow JavaScript to mimic classes, inheritance
Prototypes
• Every function stores a “prototype” object
property in it
– When we define the Point function (constructor) a
Point.prototype is created, which is an empty object {}
– Every object created with the constructor will use the
constructor’s prototype object as its prototype
• When new is called
–
–
–
–
A new object is created
The constructor’s prototype is attached to the object
Constructor is run on the new object  this
The new object is returned
The Prototype Chain
Constructors
Point()
Prototypes
constructor
prototype
distanceToOrigin
scale
Instances
prototype
x
y
prototype
x
y
Point
Point
The Prototype Chain
Constructors
Point()
Prototypes
constructor
prototype
distanceToOrigin
scale
prototype
Object()
Instances
prototype
x
y
prototype
x
y
Point
Point
constructor
prototype
toString
prototype
(null)
prototype
Object
The Prototype Chain
Point.prototype
x: 3
y: -4
__proto__
distanceToOrigin
scale
__proto__
Object.prototype
toString
__proto__
• When you ask for a property or method, JavaScript
– sees if the object itself contains the property
– recursively checks the object’s prototype
– continues up the prototype chain until the end and returns
undefined if it cannot find it.
Using the Prototype for Methods
// adding a method to the prototype
function.prototype.name = function(params) {
statements;
};
Point.prototype.distanceFromOrigin = function() {
return Math.sqrt(this.x * this.x +
this.y * this.y);
};
• Adding a property/method to a prototype will
make it available to all objects that use that
prototype
• Any prototype can be modified
– Including built-in types
Inheritance using the Prototype
function SuperClassName(parameters) { ... }
function SubClassName(parameters)
{ ... }
//Connect the prototype chain
SubClassName.prototype = new SuperClassName(parameters);
// Reset the constructor
SubClassName.prototype.constructor = SubClassName
• To make a subclass, set its prototype to an object of the
superclass
• Question: Why not this way?
–
SubClassName.prototype = SuperClassName.prototype;
Inheritance
// Constructor for Point3D "subclass"
function Point3D(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
// set it to be a "subclass" of Point
Point3D.prototype = new Point(0, 0);
// override distanceFromOrigin method to be 3D
Point3D.prototype.distanceFromOrigin = function() {
return Math.sqrt(this.x * this.x +
this.y * this.y + this.z * this.z);
};
Inheritance
• There is no equivalent of the super keyword
– no easy way to call the superclass's constructor
• no built-in way to call an overridden superclass method
– have to write it manually, e.g.
var d = Point.prototype.
distanceFromOrigin.apply(this);
Or
var d = Point.prototype.
distanceFromOrigin.call(this);
• Apply requires an array for function args
• Call requires that function args are explicitly named
function A()
{
this.x = 1;
}
// Define super class
A.prototype.DoIt = function()
{
this.x += 1;
}
// Define Method
B.prototype = new A;
// Define sub-class
B.prototype.constructor = B;
function B()
{
A.call(this);
// Call super-class constructor (if desired)
this.y = 2;
}
B.prototype.DoIt = function()
// Define Method
{
A.prototype.DoIt.call(this); // Call super-class method (if desired)
this.y += 1;
}
b = new B;
document.write((b instanceof A) + ', ' + (b instanceof B) + '<BR/>');
b.DoIt();
document.write(b.x + ', ' + b.y);
Private Members
function A()
{
var x = 7;
this.GetX = function() { return x;}
this.SetX = function(xT) { x = xT; }
}
obj = new A;
obj2 = new A;
document.write(obj.GetX() + ' ' + obj2.GetX());
obj.SetX(14);
document.write(' ' + obj.GetX() + ' ' + obj2.GetX());
• Create private members using local variables
and methods
• Closure allows access to the local variables
Namespaces
• In JavaScript, there are only two scopes
– Local and global
• Problem:
– In a large program, the namespace gets full
– Using libraries complicates this more
• Solution
– The JavaScript Module Pattern
The JavaScript Module Pattern
• Using global variables and self-executing
functions, create the equivalent of a module
• Note: self-executing functions
– Typically a function is just declared until called
– Javascript allows us to declare the function and have it
called immediately
(function() {
alert(“Hello World”);
})();
OR
(function() {
alert(“Hello World”);
}());
The JavaScript Module Pattern
var cs340.module = (function () {
// private variables and functions
var foo = 'bar';
// constructor
var module = function () {
};
// prototype
module.prototype = {
constructor: module,
something: function () {
}
};
// return the module
return module;
})();
var my_module = new cs340.module();
• Global variable
– cs340.module
• Everything else is private
inside the module
• Protected namespace
• Returned object will run
the constructor
JavaScript Module Namespace
catan.models.ClientModel = (function clientModelNameSpace(){
var ClientModel = (function ClientModelClass(){
var fullmodel = {};
function ClientModel(localConfig){
$("#debug").append("<br>In ClientModel Constructor");
}
ClientModel.prototype.initFromServer = function(success){
…
}
ClientModel.prototype.getClientPlayerName = function(){
// TODO: Return the local player's correct name
return "Sam";
}
ClientModel.prototype.getClientPlayerColor = function(){
// TODO: Return the local player's correct color
return "orange";
}
return ClientModel;
}());
return ClientModel;
}());
var clientModel = new catan.models.ClientModel();
Download