a standard defines the ECMAScript scripting language
the scripting language standardized by Ecma International in the ECMA-262
What is object ? : "Unordered collection of properties each of which contains a primitive value, object, or function."
var person = { name: "Hans", age: 26, job: "Super Junior Developer", sayName: function(){ console.log(this.name); } };
var person = { name: "Hans", age: 26, job: "Super Junior Developer", sayName: function(){ console.log(this.name); } }; person.name = "Le Roi";
var object1, object2; object1 = { a: 3.14159 } object2 = object1;
The real picture is :
[[Configurable]], [[Enumerable]], [[Writable]] are true for all properties defined directly on an object, as in the previous example.
[[Value]] attribute is set to the assigned value.
Object.defineProperty().
var person1 = {}; Object.defineProperty(person1, "name", { value: "Neo", enumerable: true, configurable: true, writable: true });
Setting configurable to false means that the property cannot be removed from the object.
Once a property has been defined as nonconfigurable, it cannot become configurable again.
var person = {}; Object.defineProperty(person, "name", { configurable: false, value: "Neo" }); Object.defineProperty(person, "name", { configurable: true, // ← error here value: "Neo" }); // this will throw an error
Note : Internet Explorer 8 was the first version to implement Object .defineProperty(). Unfortunately, the implementation is extremely limited. This method can be used only on DOM objects and can create only accessor properties.
[[Configurable]], [[Enumerable]] are true for all properties defined directly on an object, as in the previous example.
When an accessor property is read from, the getter function [[Get]] is called
when an accessor property is written to, the setter function [[Set]] is called.
It is not possible to define an accessor property explicitly so you must use Object.defineProperty().
var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, “year”, { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2
It’s not necessary to assign both a getter and a setter. Assigning just a getter means that the property cannot be written to and attempts to do so will be ignored.
var descriptor = Object.getOwnPropertyDescriptor(book, "_year"); alert(descriptor.value); //2004 alert(descriptor.configurable); //true alert(typeof descriptor.get); //"undefined" var descriptor = Object.getOwnPropertyDescriptor(book, "year"); alert(descriptor.value); //undefined alert(descriptor.enumerable); //false alert(typeof descriptor.get); //"function"
It’s not necessary to assign both a getter and a setter. Assigning just a getter means that the property cannot be written to and attempts to do so will be ignored.
console.log(descriptor); Object {get: function, set: function, enumerable: false, configurable: false }
The factory pattern is a well-known design pattern used in software engineering to abstract away the process of creating specific objects
function Person(name, age, job) { return { name : name, age : age, job : job, run : function() { alert(name + " is running!"); } } } var person1 = Person("Hans") person1.run(); person1 instanceof Object; //true person1 instanceof Person; //false
"Oh my god, I’m not a person ... but I can run. What am I really ?"
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person1 = new Person(“Le Roi”, 27, “Super Star Singer”); var person2 = new Person(“Le Hai Thinh”, 26, “Psychology Doctor”); alert(person1.constructor === Person); //true alert(person2.constructor === Person); //true
There is no object being created explicitly.
The properties and method are assigned directly onto the this object.
There is no return statement.
alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true
All custom objects inherit from Object.
Constructors are just functions
Function that is called with the new operator acts as a constructor
//use as a constructor var person = new Person("Le Roi", 26, "Singer"); person.sayName(); //"Le Roi" //call as a function Person("Le Tuon Roi", 27, "Graphic Designer of NAU"); //adds to window window.sayName(); //"Le Tuon Roi" //call in the scope of another object var o = new Object(); Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen" o instanceof Person // "false"
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = new Function(“alert(this.name)”); //logical equivalent } alert(person1.sayName === person2.sayName); //false
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); }
Each function is created with a prototype property, which is an object containing properties and methods that should be available to instances of a particular reference type.
This object is a prototype for the object to be created once the constructor is called.
All of its properties and methods are shared among object instances.
By default, all prototypes automatically get a property called constructor that points back to the function on which it is a property
There is no standard way to access [[Prototype]] from script, but Firefox, Safari, and Chrome all support a property on every object called __proto__., in other implementations, this property is completely hidden from script.
function Person(){ } Person.prototype.name = "Hans"; Person.prototype.age = 26; Person.prototype.job = "Super Junior"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Hans" var person2 = new Person(); person2.sayName(); //"Hans" alert(person1.sayName === person2.sayName); //true
function Person(){ } Person.prototype.name = “Thang”; Person.prototype.age = 26; Person.prototype.job = “Minior”; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = “Le Roi”; alert(person1.name); //”Le Roi” - from instance alert(person2.name); //” Thang” - from prototype delete person1.name; alert(person1.name); //”Thang” - from the prototype // Yeah, we should remove Le Roi, I dun like that name.
Returns true only if a property of the given name exists on the object instance, as in this example:
alert(person1.hasOwnProperty(“name”)); //false person1.name = “Trang”; alert(person1.name); //”Trang” - from instance alert(person1.hasOwnProperty(“name”)); //true
Returns true when a property of the given name is accessible by the object, which is to say that the property may exist on the instance or on the prototype.
alert(person2.hasOwnProperty(“name”)); //false alert(“name” in person2); //true
function Person(){ } Person.prototype = { name : “Nicholas”, age : 29, job : “Software Engineer”, sayName : function () { alert(this.name); } };
But
var friend = new Person(); alert(friend instanceof Object); //true alert(friend instanceof Person); //true alert(friend.constructor === Person); //false alert(friend.constructor === Object); //true
function Person(){ } Person.prototype = { constructor: Person, name : “Nicholas”, age : 29, job : “Software Engineer”, sayName : function () { alert(this.name); } };
Using Object.defineProperty()
//ECMAScript 5 only – restore the constructor Object.defineProperty(Person.prototype, “constructor”, { enumerable: false, value: Person });
function Person(){ } var friend = new Person(); Person.prototype = { constructor: Person, name : “Nicholas”, age : 29, job : “Software Engineer”, sayName : function () { alert(this.name); } }; friend.sayName(); //error
Why it throws error ?
function Person(){} Person.prototype = { constructor: Person, name : “Le Roi”, age : 29, job : “Singer”, friends : [“Thuy TOP”, “Phuong Trinh”], sayName : function () { alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.friends.push(“Phi Thanh Van”); alert(person1.friends); // ”Thuy TOP,Phuong Trinh,Phi Thanh Van” alert(person2.friends); // ”Thuy TOP,Phuong Trinh,Phi Thanh Van” alert(person1.friends === person2.friends); //true
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = [“Trang”, “Vu”]; } Person.prototype = { constructor: Person, sayName : function () { alert(this.name); } }; var person1 = new Person(“Hans”, 26, “Terrorist”); var person2 = new Person(“Thang”, 23, “Cop”); person1.friends.push(“Thang”); alert(person1.friends); //” Trang,Vu,Thang” alert(person2.friends); //” Trang,Vu” alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true
Oppz ! Not that guy, I mean Prototype Chaining, not him...
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.subproperty; }; var instance = new SubType(); alert(instance.getSuperValue()); //true
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); //try to add new methods - this nullifies the previous line SubType.prototype = {  getSubValue : function (){ return this.subproperty; }, someOtherMethod : function (){ return false; } }; var instance = new SubType(); alert(instance.getSuperValue()); //error!
function SubType(){ } //inherit from SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push(“black”); alert(instance1.colors); //”red,blue,green,black” var instance2 = new SubType(); alert(instance2.colors); //”red,blue,green,black”
function SuperType(){ this.colors = [“red”, “blue”, “green”]; } function SubType(){ //inherit from SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push(“black”); alert(instance1.colors); //”red,blue,green,black” var instance2 = new SubType(); alert(instance2.colors); //”red,blue,green
function SuperType(name){ this.name = name; } function SubType(){ //inherit from SuperType passing in an argument SuperType.call(this, “Le Roi”); //instance property this.age = 29; } var instance = new SubType(); alert(instance.name); //”Le Roi”; alert(instance.age); //29
function SuperType(name){ this.name = name; this.colors = [“red”, “blue”, “green”]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ //inherit properties SuperType.call(this, name); this.age = age; } //inherit methods SubType.prototype = new SuperType(); SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType(“Le Roi”, 26); instance1.colors.push(“black”); alert(instance1.colors); //”red,blue,green,black” instance1.sayName(); //”Le Roi”; instance1.sayAge(); //26 var instance2 = new SubType(“Le Coc”, 27); alert(instance2.colors); //”red,blue,green” instance2.sayName(); //”Le Coc”; instance2.sayAge(); //27
“Hello, I’m Douglas Crockford, a Hans’s friend”
function object(o){ function F(){} F.prototype = o; return new F(); } var person = { name: “Douglas”, friends: [“Quy”, “Thanh”, “Thinh”] }; var anotherPerson = object(person); anotherPerson.name = “Le Roi”; anotherPerson.friends.push(“Vu”); var yetAnotherPerson = object(person); yetAnotherPerson.name = “Linda Kieu”; yetAnotherPerson.friends.push(“Thang”); alert(person.friends); //”Quy,Thanh,Thinh,Vu,Thang”
var person = { name: “Douglas”, friends: [“Quy”, “Thanh”, “Thinh”] }; var anotherPerson = Object.create(person); anotherPerson.name = “Le Roi”; anotherPerson.friends.push(“Vu”); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = “Linda Kieu”; yetAnotherPerson.friends.push(“Thao”); alert(person.friends); //” Quy,Thanh,Thinh,Vu,Thao”
Important contact information goes here.