mirror of
				https://github.com/flynx/Course-JavaScript.git
				synced 2025-11-04 05:50:08 +00:00 
			
		
		
		
	the main part of js-oop.js is done, need to proof read and do the last section...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									e63028904c
								
							
						
					
					
						commit
						a803110c56
					
				
							
								
								
									
										187
									
								
								js-oop.js
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								js-oop.js
									
									
									
									
									
								
							@ -149,9 +149,9 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// Let's look at a number of attributes that new sets:
 | 
					// Let's look at a number of attributes that new sets:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a.__proto__		// -> {} 
 | 
						a.__proto__			// -> {} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a.constructor	// -> [Function A]
 | 
						a.constructor		// -> [Function A]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// These are what makes this fun, lets write a more complete new 
 | 
					// These are what makes this fun, lets write a more complete new 
 | 
				
			||||||
@ -202,18 +202,18 @@
 | 
				
			|||||||
	a.x = 'a!'
 | 
						a.x = 'a!'
 | 
				
			||||||
	b.x = 'b!'
 | 
						b.x = 'b!'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a.x				// -> 'a!'
 | 
						a.x					// -> 'a!'
 | 
				
			||||||
	a.y				// -> 321
 | 
						a.y					// -> 321
 | 
				
			||||||
	a.z				// -> 333
 | 
						a.z					// -> 333
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// These values are accessible from all objects constructed by A since
 | 
					// These values are accessible from all objects constructed by A since
 | 
				
			||||||
// all of them point to A with both the .constructor and .__proto__ 
 | 
					// all of them point to A with both the .constructor and .__proto__ 
 | 
				
			||||||
// attributes
 | 
					// attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b.x				// -> 'b!'
 | 
						b.x					// -> 'b!'
 | 
				
			||||||
	b.y				// -> 321
 | 
						b.y					// -> 321
 | 
				
			||||||
	b.z				// -> 333
 | 
						b.z					// -> 333
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -246,8 +246,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Now we can access both attributes inherited from 'O' and 'A'...
 | 
					// Now we can access both attributes inherited from 'O' and 'A'...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a.o				// -> 0
 | 
						a.o					// -> 0
 | 
				
			||||||
	a.a				// -> 1
 | 
						a.a					// -> 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The check is done specifically in this order, thus attributes can 
 | 
					// The check is done specifically in this order, thus attributes can 
 | 
				
			||||||
@ -259,7 +259,7 @@
 | 
				
			|||||||
	O.x = 'came from O'
 | 
						O.x = 'came from O'
 | 
				
			||||||
	A.prototype.x = 'came from A'
 | 
						A.prototype.x = 'came from A'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a.x				// -> 'came from O'
 | 
						a.x					// -> 'came from O'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// In both inheritance mechanisms, each step is checked via the same 
 | 
					// In both inheritance mechanisms, each step is checked via the same 
 | 
				
			||||||
@ -276,8 +276,8 @@
 | 
				
			|||||||
	b.y = 2
 | 
						b.y = 2
 | 
				
			||||||
	var c = Object.create(b)
 | 
						var c = Object.create(b)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	c.x				// -> 1
 | 
						c.x					// -> 1
 | 
				
			||||||
	c.y				// -> 2
 | 
						c.y					// -> 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Creating an inheritance chain via the constructor mechanism is a bit
 | 
					// Creating an inheritance chain via the constructor mechanism is a bit
 | 
				
			||||||
@ -306,8 +306,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var c = new C()
 | 
						var c = new C()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.x				// -> 1
 | 
						c.x					// -> 1
 | 
				
			||||||
	c.y				// -> 2
 | 
						c.y					// -> 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -317,11 +317,10 @@
 | 
				
			|||||||
// An object is considered an instance of its' constructor and all other 
 | 
					// An object is considered an instance of its' constructor and all other 
 | 
				
			||||||
// constructors in the inheritance chain.
 | 
					// constructors in the inheritance chain.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c instanceof C	// -> true
 | 
						c instanceof C		// -> true
 | 
				
			||||||
	c instanceof B	// -> true
 | 
						c instanceof B		// -> true
 | 
				
			||||||
	c instanceof A	// -> true
 | 
						c instanceof A		// -> true
 | 
				
			||||||
	c instanceof Object
 | 
						c instanceof Object // -> true
 | 
				
			||||||
					// -> true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This also works for manually created objects
 | 
					// This also works for manually created objects
 | 
				
			||||||
@ -396,6 +395,11 @@
 | 
				
			|||||||
	typeof function(){}	// -> 'function'
 | 
						typeof function(){}	// -> 'function'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: the "non-object" term is not entirely correct here, they can
 | 
				
			||||||
 | 
					// 		be called "frozen" objects in ES5 speak, but that is outside the
 | 
				
			||||||
 | 
					// 		scope of this document.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Methods and the value of 'this'
 | 
					// Methods and the value of 'this'
 | 
				
			||||||
// -------------------------------
 | 
					// -------------------------------
 | 
				
			||||||
@ -403,8 +407,7 @@
 | 
				
			|||||||
// A method is simply an attribute that references a function.
 | 
					// A method is simply an attribute that references a function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 	function f(){
 | 
					 	function f(){
 | 
				
			||||||
 		console.log(this)
 | 
							return this
 | 
				
			||||||
 		this.a = 1
 | 
					 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var o = { f: f }
 | 
						var o = { f: f }
 | 
				
			||||||
@ -420,79 +423,75 @@
 | 
				
			|||||||
// A simple way to think about this is that 'this' always points to the 
 | 
					// A simple way to think about this is that 'this' always points to the 
 | 
				
			||||||
// "context" of the function call.
 | 
					// "context" of the function call.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// This context can be:
 | 
					// And there are two distinct cases here:
 | 
				
			||||||
// 	- implicit
 | 
					// 	- function call / implicit context
 | 
				
			||||||
// 		- root context
 | 
					// 	- new call / implicit context
 | 
				
			||||||
 			f()
 | 
					// 	- method call / explicit context
 | 
				
			||||||
						// 'window', 'global' or 'module' is implied, 
 | 
					 | 
				
			||||||
						// in strict mode this is null.
 | 
					 | 
				
			||||||
						// the same as:
 | 
					 | 
				
			||||||
						// 		window.f()
 | 
					 | 
				
			||||||
// 		- 'new' context
 | 
					 | 
				
			||||||
 			new f()		// here a context will be created and passed to
 | 
					 | 
				
			||||||
 						// 'f's 'this', for more details on what 'new'
 | 
					 | 
				
			||||||
 						// does see: "The Constructor Mechanism" section.
 | 
					 | 
				
			||||||
// 	- explicit:
 | 
					 | 
				
			||||||
// 		- the object on the left side of "." or the [ ] operators:
 | 
					 | 
				
			||||||
 			o.f()		// o is the context
 | 
					 | 
				
			||||||
 			o['f']()	// the same as the above
 | 
					 | 
				
			||||||
// 		- the object explicitly passed to .call(..) or .apply(..) methods
 | 
					 | 
				
			||||||
// 		  as first argument:
 | 
					 | 
				
			||||||
 		  	f.call(o)	// o is the context
 | 
					 | 
				
			||||||
 		  	f.apply(o)	// o is the context
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Properties
 | 
					 | 
				
			||||||
// ----------
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// A property is a special attribute that has a getter, setter methods
 | 
					 | 
				
			||||||
// and/or other optional configuration.
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// A good property example is .length of Array objects.
 | 
					// 1) function call (implicit)
 | 
				
			||||||
 | 
					//	In the first case the context is either global/window/module which 
 | 
				
			||||||
 | 
					//	ever is the root context in a given implementation or null in ES5
 | 
				
			||||||
 | 
					//	strict mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var o = {
 | 
						f()					// -> window/global/module
 | 
				
			||||||
		get x(){
 | 
					
 | 
				
			||||||
			return this.data || 123
 | 
					//	Strict mode example:
 | 
				
			||||||
		},
 | 
					//
 | 
				
			||||||
		set x(value){
 | 
						function strict_f(){
 | 
				
			||||||
			this.data = value
 | 
							'use strict'
 | 
				
			||||||
		},
 | 
							return this
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o.x				// -> 123
 | 
						strict_f()			// -> undefined
 | 
				
			||||||
	o.x = 4
 | 
					 | 
				
			||||||
	o.x				// -> 4
 | 
					 | 
				
			||||||
	o.x = undefined
 | 
					 | 
				
			||||||
	o.x				// -> 123
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// As for any other attribute, deleting a local property x will remove
 | 
					 | 
				
			||||||
// it from the containing  object...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	delete o.x
 | 
					 | 
				
			||||||
	o.x				// -> undefined
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The above code is a shorthand for:
 | 
					// 2) new call (implicit)
 | 
				
			||||||
 | 
					// 	Here as we have discussed before, this is assigned a new object with
 | 
				
			||||||
 | 
					// 	some attributes set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Object.defineProperty(o, 'y', {
 | 
						new f()				// -> {}
 | 
				
			||||||
		get: function() {
 | 
					 | 
				
			||||||
			return this.data || 123
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		set: function(name) {
 | 
					 | 
				
			||||||
			this.data = value
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// XXX other property attributes...
 | 
					
 | 
				
			||||||
// 		get
 | 
					// 3) method call (explicit)
 | 
				
			||||||
// 		set
 | 
					// 	In the method call context this is set to the object from which the
 | 
				
			||||||
// 		value
 | 
					// 	method is called, i.e. the object left of the '.' or [ ] attribute 
 | 
				
			||||||
// 			if set get/set are not possible...
 | 
					// 	access operators...
 | 
				
			||||||
// 		writable (false)
 | 
					
 | 
				
			||||||
// 		configurable (false)
 | 
						o.f()				// -> o
 | 
				
			||||||
// 			is it possible to change this configurations later...
 | 
						o['f']()			// -> o
 | 
				
			||||||
// 		enumerable (false)
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 	...or an explicitly passed to .call(..) / .apply(..) object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f.call(o)			// -> o
 | 
				
			||||||
 | 
						f.apply(o)			// -> o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ES5 also defines a third way to make method calls: Object.bind which
 | 
				
			||||||
 | 
					// creates a new function where 'there' is bound to the supplied object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var ff = f.bind(o)
 | 
				
			||||||
 | 
						ff()				// -> o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: all of the above 5 calls are the same.
 | 
				
			||||||
 | 
					// NOTE: the resulting from .bind(..) function will ignore subsequent
 | 
				
			||||||
 | 
					// 		.bind(..), .call(..) and .apply(..) method calls and this will 
 | 
				
			||||||
 | 
					// 		always be the original bound object.
 | 
				
			||||||
 | 
					// NOTE: the difference between strict and "quirks" modes is in the 
 | 
				
			||||||
 | 
					// 		following:
 | 
				
			||||||
 | 
					// 		In quirks mode a function call is always done in the root 
 | 
				
			||||||
 | 
					// 		context, it's like implicitly calling a method of the global
 | 
				
			||||||
 | 
					// 		object:
 | 
				
			||||||
 | 
								f() === window.f()	
 | 
				
			||||||
 | 
											// -> true
 | 
				
			||||||
 | 
					//		In strict mode these are two different things, a function call
 | 
				
			||||||
 | 
					//		is done without a context ('this' is undefined) while calling
 | 
				
			||||||
 | 
					//		the same function via the global object is essentially a method
 | 
				
			||||||
 | 
					//		call, setting 'this' to what is to the left of the attribute 
 | 
				
			||||||
 | 
					//		access operator:
 | 
				
			||||||
 | 
								strict_f() !== window.strict_f()	
 | 
				
			||||||
 | 
											// -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -501,6 +500,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*********************************************************************/
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// NOTE: several topics available in ES5 are intentionally excluded 
 | 
				
			||||||
 | 
					// 		from this document, these include:
 | 
				
			||||||
 | 
					// 			- properties
 | 
				
			||||||
 | 
					// 			- freezing/sealing
 | 
				
			||||||
 | 
					// 		The general motivation for this is simple: they introduce 
 | 
				
			||||||
 | 
					// 		complexity and restrictions without giving any real benefits 
 | 
				
			||||||
 | 
					// 		in the common case.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 		Cases where these features "might" be useful are:
 | 
				
			||||||
 | 
					// 			- language design / language extending
 | 
				
			||||||
 | 
					// 			- library code
 | 
				
			||||||
 | 
					// 		Neither of these is a common case and the use of these features
 | 
				
			||||||
 | 
					// 		for library code is debatable.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
/**********************************************************************
 | 
					/**********************************************************************
 | 
				
			||||||
* vim:set ts=4 sw=4 :                                                */
 | 
					* vim:set ts=4 sw=4 :                                                */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user