So rather than writing down clumsy and possibly mistaken explanations myself,
it seems better to introduce bloggers or pages by people
who explain things more kindly than I can.
In other words, it's for recycling resources and revitalizing existing blogs.
Although I don't know them personally, through this connection
being able to introduce these skilled people
is personally an honor.
I hope those who wrote these will always feel this sense of honor going forward.
Ah,
if you would like this removed, leave a comment and I will take it down right away.
There is no other intention.
Please understand in advance.
The second source is
Gyui's Spring Note.
http://godpage.springnote.com/pages/4223711
There you can find information not only on JavaScript but also on many other programs.
Object
Everything in JavaScript is an object.
-> An object is a collection of properties, and is very similar to a hash data structure.
Object creation
How most object-oriented languages create objects
Class exists -> create object | inherit from class
How JavaScript creates objects (prototype inheritance)
Object -> create a new object | inherit from another object
constructor property: exists on every object and points to the function that created the object.
-> used when copying an object
Superclass and subclass
Object is the superclass of all classes.
That means the Rectangle object above inherits properties from Rectangle.prototype and Object.prototype.
When looking for a Rectangle property,
1. Check the object's own properties first (if none, move on).
2. Check Rectangle.prototype properties (if none, move on).
3. Check Object.prototype properties (there is nowhere else to go after that).
Properties of Object
constructor - references the JavaScript function that created the object
apply() and call() methods
Every function has call() and apply() methods defined on it.
Changing the meaning of this
public (prototype) and privileged (closure) methods
public - shared method
privileged method: not attached when the code is first compiled, but added during execution, so it is created dynamically.
Examples
- /**
* @author gyus
*/ - // object creation 1 - create it directly
var obj = new Object(); - obj.val = 5;
obj.click = function(){
alert("obj click ok");
} - // object creation 2 - create it in JSON {key:value} form
var obj2 = {
val : 5,
click : function(){
alert("obj2 click ok");
}
} - //obj.click();
//obj2.click();
// declare a function that plays the role of a class
function Movie(title){
this.title = title;
}
// create an object from a function and inspect the constructor property
var movie1 = new Movie("G.I.Joe");- //alert("movie's Title : " + movie1.title);
- //alert(movie1.constructor);
//alert(movie1.constructor == Movie); - // since a constructor function is also just a function, what happens if you execute it directly? What does this point to?
- Movie('The Lord of the ring');
- // -> it becomes global-scope this, so it turns into a property of window.
//alert(window.title); - // Constructor, second example
function Supplies(){} // constructor function for supplies - var pencil = new Supplies(); // create a pencil object
// create an eraser using the constructor function
var eraser = new pencil.constructor(); // == Supplies() you can duplicate a new object easily and effectively! - //alert("Constructor check : " + pencil.constructor == eraser.constructor);
/*** public (prototype), private (inner function), privileged (closure) methods ***/- // add methods through the prototype property
function User(name, age){
this.name = name;
this.age = age;
} - User.prototype.getName = function(){
return this.name;
} - User.prototype.getAge = function(){
return this.age;
} - var user = new User("Seung-gyu", "28");
- // let's check it~
//alert("name : " + user.getName() + " | age : " + user.getAge() );
// less efficient than building prototype methods, but more flexible! -> can be used often.
function User2(name, age){
// calculate the user's birth year
var year = (new Date()).getFullYear() - age;
// create a privileged method that can access the year variable and also be used externally.
this.getYearBorn = function(){
return year;
}
}- var user2 = new User2("Mr. Park","28");
//alert(user2.getYearBorn()); - // cannot access the object's private year property
//alert(user2.year);
/**
* make a variable private
*/- function Rectangle(w,h){
// this constructor does not store width and height properties directly on the initialized object.
// instead, it defines accessor methods on the object.
// these methods are closures, and width and height remain inside the scope chain.
this.getWidth = function(){return w;}
this.getHeight = function(){return h;}
} - // add method
Rectangle.prototype.area = function(){
return this.getWidth() * this.getHeight();
} - var r1 = new Rectangle(10,5);
- //alert("width : " + r1.w); //undifined
//alert("height : " + r1.h); //undifined - //alert("width : " + r1.getWidth());
//alert("height : " + r1.getHeight());
//alert("area : " + r1.area()); - // make a toString method
Rectangle.prototype.toString = function(){
return "[Width : "+this.getWidth()+" ]\n"
+"[Height : "+this.getHeight()+" ]\n"
+"[Area : "+this.area()+" ]";
} - //alert(r1.toString());
- // superclass and subclass (prototype inheritance)
- /**
* methods of Object
*
* hasOwnProperty() - checks whether the specified property exists
* isPrototypeOf() - checks whether this object is the prototype of the specified object
* propertyIsEnumerable() - checks whether the specified property exists and can be iterated with a for/in loop
* toLocaleString() - returns a localized string representation of the object; usually calls toString(), but can be overridden
* toString() - returns the string representation of the object
* valueOf() - returns the primitive value associated with the object, if there is one
*/
// use call & apply to change the meaning of this
function plus(x, y){
alert(x + " + " + y + " = " + (x + y));
}- function minus(x, y){
alert(x + " - " + y + " = " + (x - y));
} - function multi(x,y){
alert(x + " x " + y + " = " + (x * y));
}
function arithmatic(x, y, operator){
if(operator == "plus")
plus.call(this, x, y);
else if(operator == "minus")
minus.apply(this,[x,y]);
else if(operator == "multi")
multi.call(this, x, y);
} - new arithmatic(1,2,'plus');
new arithmatic(1,2,'minus');
new arithmatic(3,5,'multi');
// let us create a class that inherits from Rectangle
// rectangle class that contains position information
function PositionedRectangle(x,y,w,h){
// call the superclass constructor of the new object
// use call() so the constructor can be invoked as a method of the object being initialized.
// this is called constructor chaining
Rectangle.call(this,w,h);
this.x = x;
this.y = y;
}
// if you use new PositionedRectangle(), the superclass becomes Object, so explicitly set the superclass to Rectangle.
PositionedRectangle.prototype = new Rectangle();- // delete unnecessary properties
delete PositionedRectangle.prototype.width;
delete PositionedRectangle.prototype.height; - // because the prototype object was created using Rectangle(),
// the constructor property points to the Rectangle() constructor.
// but because we want the constructor to become PositionedRectangle(),
// we reset the constructor property reference.
PositionedRectangle.prototype.constructor = PositionedRectangle;
// the desired object has been created. - // methods can be added here
PositionedRectangle.prototype.contains = function(x,y){
return(x > this.x && x< this.x + this.width && y> this.y && y < this.y + this.height);
} - // conclusion: building subclasses is trickier than it looks.
// procedure
// 1. call the superclass constructor from the subclass constructor
// 2. explicitly make the prototype object an instance of the superclass
// 3. then explicitly reset the prototype object's constructor property
// 4. remove properties created by the superclass constructor if they are unnecessary - var r2 = new PositionedRectangle(2,2,2,2);
//alert(r2.contains(3,3));
//alert(r2.area()); - //alert(r2.x + " | " + r2.y + " | " + r2.width + " | " + r2.height);
- //alert(r2 instanceof PositionedRectangle && r2 instanceof Rectangle && r2 instanceof Object);
- // because it was not overridden, Rectangle's method is called
//alert(r2.toString()); - // constructor chaining
PRectangle.prototype.superclass = Rectangle;
function PRectangle(x,y,w,h){
// constructor of the parent class
this.superclass(w,h);
this.x = x;
this.y = y;
}
// override toString()
PRectangle.prototype.toString = function(){
return "(" + this.x + "," + this.y + ")" + this.superclass.prototype.toString.apply(this) // chain PositionedRectangle fields into the superclass
}
