mirror of
				https://github.com/flynx/Course-JavaScript.git
				synced 2025-11-04 05:50:08 +00:00 
			
		
		
		
	more work on the OOP doc...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									ad14667008
								
							
						
					
					
						commit
						351ec981c7
					
				
							
								
								
									
										171
									
								
								js-oop.js
									
									
									
									
									
								
							
							
						
						
									
										171
									
								
								js-oop.js
									
									
									
									
									
								
							@ -31,8 +31,11 @@
 | 
				
			|||||||
	b.z					// -> 3
 | 
						b.z					// -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// What we see is that if the attribute is not found in the current 
 | 
					// What we see is that if the attribute is not found in the current 
 | 
				
			||||||
// object it resolves to the object's "prototype" and so on, these 
 | 
					// object it resolves to the next object, and so on, this next object is
 | 
				
			||||||
// chians can of any length.
 | 
					// called "prototype". 
 | 
				
			||||||
 | 
					// These prototype chains can be of any length.
 | 
				
			||||||
 | 
					// Cycles in prototype chains are not allowed, see note further down for
 | 
				
			||||||
 | 
					// an example.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Note that this works for reading, when writing or deleting we are 
 | 
					// Note that this works for reading, when writing or deleting we are 
 | 
				
			||||||
// affecting ONLY the local object and attributes explicitly defined in
 | 
					// affecting ONLY the local object and attributes explicitly defined in
 | 
				
			||||||
@ -58,8 +61,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Now back to the mechanism that makes all of this work...
 | 
					// Now back to the mechanism that makes all of this work...
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// A couple of easy ways to see the local and non-local sets of 
 | 
					// First we'll try couple of easy ways to see the local and non-local 
 | 
				
			||||||
// attributes:
 | 
					// sets of attributes:
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// show local or "own" only attribute names (keys)...
 | 
						// show local or "own" only attribute names (keys)...
 | 
				
			||||||
	Object.keys(b)		// -> z
 | 
						Object.keys(b)		// -> z
 | 
				
			||||||
@ -74,14 +77,23 @@
 | 
				
			|||||||
	b.hasOwnProperty('x')	// -> false
 | 
						b.hasOwnProperty('x')	// -> false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// What happens under the hood is very simple:
 | 
					// What happens under the hood is very simple: b references it's 
 | 
				
			||||||
 | 
					// "prototype" via the .__proto__ attribute:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b.__proto__ === a	// -> true
 | 
						b.__proto__ === a	// -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// We can read/set this special attribute just like any other attribute 
 | 
				
			||||||
 | 
					// on most systems.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// NOTE: we did not see .__proto__ in the list of accessible attributes
 | 
					// NOTE: we did not see .__proto__ in the list of accessible attributes
 | 
				
			||||||
// 		because it is a special attributes, it is implemented internally
 | 
					// 		because it is a special attribute, it is implemented internally
 | 
				
			||||||
// 		and is not enumerable.
 | 
					// 		and is not enumerable.
 | 
				
			||||||
 | 
					// NOTE: cyclic prototype chains are actively not allowed, e.g. creating
 | 
				
			||||||
 | 
					// 		a chain like the following will fail:
 | 
				
			||||||
 | 
					// 			var a = {}
 | 
				
			||||||
 | 
					// 			var b = Object.creating(a)
 | 
				
			||||||
 | 
					// 			a.__proto__ = b
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Thus, we could define our own create function like this:
 | 
					// Thus, we could define our own create function like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -102,11 +114,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Turns out it is, and it points to Object's prototype
 | 
					// Turns out it is, and it points to Object's prototype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	x.__proto__ === Object.prototye
 | 
						x.__proto__ === Object.prototype
 | 
				
			||||||
						// -> true
 | 
											// -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// We will discuss what this means and how we can use this in the next 
 | 
					// We will discuss what this means and how we can use this in the next 
 | 
				
			||||||
// sections...
 | 
					// sections...
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// As a side note, Object.prototype is the "root" most object in 
 | 
				
			||||||
 | 
					// JavaScript and usually is "terminated" with null, i.e.:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Object.prototype.__proto__ === null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// We'll also need this a bit later...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -116,7 +135,7 @@
 | 
				
			|||||||
// JavaScript provides a second, complementary mechanism to inherit 
 | 
					// JavaScript provides a second, complementary mechanism to inherit 
 | 
				
			||||||
// attributes, it resembles the class/object relationship in languages
 | 
					// attributes, it resembles the class/object relationship in languages
 | 
				
			||||||
// like C++ but this resemblance is on the surface only, as it still 
 | 
					// like C++ but this resemblance is on the surface only, as it still 
 | 
				
			||||||
// uses the same prototype mechanism as the above.  
 | 
					// uses the same prototype mechanism as basis as described above.  
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// We will start by creating a "constructor":
 | 
					// We will start by creating a "constructor":
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@ -131,7 +150,17 @@
 | 
				
			|||||||
	var a = new A()
 | 
						var a = new A()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// what 'new' does here is:
 | 
					// Some terminology:
 | 
				
			||||||
 | 
					// - in the above use-case A is called a constructor,
 | 
				
			||||||
 | 
					// - the object returned by new is called an "instance" (in this case 
 | 
				
			||||||
 | 
					//   assigned to a),
 | 
				
			||||||
 | 
					// - the attributes set by the constructor (x and y) are called 
 | 
				
			||||||
 | 
					//   "instance attributes" and are not shared (obviously) between 
 | 
				
			||||||
 | 
					//   different instances, rather they are "constructed" for each 
 | 
				
			||||||
 | 
					//   instance independently.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Let's look in more detail at what 'new' does here:
 | 
				
			||||||
// 	1) creates an empty object
 | 
					// 	1) creates an empty object
 | 
				
			||||||
// 	2) sets a bunch of attributes on it, we'll skim this part for now
 | 
					// 	2) sets a bunch of attributes on it, we'll skim this part for now
 | 
				
			||||||
// 	3) passes the new object to the constructor via 'this'
 | 
					// 	3) passes the new object to the constructor via 'this'
 | 
				
			||||||
@ -146,63 +175,74 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var b = construct(A)
 | 
						var b = construct(A)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// But what does make this interesting? At this point this all looks like 
 | 
					// But at this point this all looks like all we did is move the attribute
 | 
				
			||||||
// all we did is move attribute definition from a literal object notation 
 | 
					// definition from a literal object notation into a constructor function,
 | 
				
			||||||
// into a constructor function, effectively adding complexity. What are we 
 | 
					// effectively adding complexity. 
 | 
				
			||||||
// getting back from this?
 | 
					// And now instead of "inheriting" attributes we make a new set for each
 | 
				
			||||||
 | 
					// individual instance.
 | 
				
			||||||
 | 
					// So hat are we getting back from this?
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Let's look at a number of attributes that new sets:
 | 
					// To answer this question we will need to look deeper under the hood,
 | 
				
			||||||
 | 
					// specifically at a couple of special attributes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// we saw this one before...
 | 
				
			||||||
	a.__proto__			// -> {} 
 | 
						a.__proto__			// -> {} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// this points back to the constructor...
 | 
				
			||||||
	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 
 | 
				
			||||||
// implementation:
 | 
					// re-implementation:
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	function construct(func, args){
 | 
						function construct(func, args){
 | 
				
			||||||
		var obj = {}
 | 
							var obj = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// set some special attributes...
 | 
				
			||||||
		obj.constructor = func
 | 
							obj.constructor = func
 | 
				
			||||||
		obj.__proto__ = func.prototype
 | 
							obj.__proto__ = func.prototype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// call the constructor...
 | 
				
			||||||
		var res = func.apply(obj, args)
 | 
							var res = func.apply(obj, args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// handle the return value of the constructor...
 | 
				
			||||||
		if(res instanceof Object){
 | 
							if(res instanceof Object){
 | 
				
			||||||
			return res
 | 
								return res
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		return obj
 | 
							return obj
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var b = construct(A)
 | 
						var b = construct(A)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Notice that we return the resulting object in a more complicated
 | 
					// There are two important things we added here:
 | 
				
			||||||
// way, this will come in handy later.
 | 
					// 1) we now explicitly use the .prototype attribute that we saw earlier
 | 
				
			||||||
// 
 | 
					// 2) we return the resulting object in a more complicated way
 | 
				
			||||||
// Also notice that 'prototype' from the end of the previous section.
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// First let us cover the default. Each time a function is created in
 | 
					// Each time a function is created in JavaScript it will get a new empty
 | 
				
			||||||
// JavaScript it will get a new empty object assigned to it's .prototype
 | 
					// object assigned to it's .prototype attribute.
 | 
				
			||||||
// attribute.
 | 
					// On the function level, this is rarely used, but this object is very 
 | 
				
			||||||
// On the function level, in general, this is not used, but this is very
 | 
					 | 
				
			||||||
// useful when the function is used as a constructor.
 | 
					// useful when the function is used as a constructor.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// As we can see from the code above, the resulting object's .__proto__
 | 
					// As we can see from the code above, the resulting object's .__proto__
 | 
				
			||||||
// points to the constructor's .prototype, from the previous section 
 | 
					// points to the constructor's .prototype, this means not-own the 
 | 
				
			||||||
// this means that attributes accessed via that object are resolved to 
 | 
					// attributes accessed via that object are resolved to the prototype.
 | 
				
			||||||
// the prototype.
 | 
					// In the default case this is true, but in general it's a bit more 
 | 
				
			||||||
// In the default case this is true.
 | 
					// flexible, we'll see this in the next section.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// So if we add stuff to the constructor's .prototype they should get 
 | 
					// And the way we handle the return value makes it possible for the 
 | 
				
			||||||
// resolved from the object
 | 
					// constructor to return a custom object rather than use the one 
 | 
				
			||||||
 | 
					// provided in its "this" by new.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// So if we add stuff to the constructor's .prototype they should be 
 | 
				
			||||||
 | 
					// accessible from the object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	A.prototype.x = 123
 | 
						A.prototype.x = 123
 | 
				
			||||||
	a.constructor.prototype.y = 321
 | 
						a.constructor.prototype.y = 321
 | 
				
			||||||
	a.__proto__.z = 333
 | 
						a.__proto__.z = 333
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// for illustration, some object own attributes
 | 
						// for illustration, we'll set some object own attributes
 | 
				
			||||||
	a.x = 'a!'
 | 
						a.x = 'a!'
 | 
				
			||||||
	b.x = 'b!'
 | 
						b.x = 'b!'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -220,18 +260,43 @@
 | 
				
			|||||||
	b.z					// -> 333
 | 
						b.z					// -> 333
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This works for any constructor, including built-in constructors and
 | 
				
			||||||
 | 
					// since name resolution happens in runtime all instances will get the 
 | 
				
			||||||
 | 
					// new functionality live, as it is defined:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// a "class method", like .keys(..) but return all available keys...
 | 
				
			||||||
 | 
						Object.allKeys = function(o){
 | 
				
			||||||
 | 
							var res = []
 | 
				
			||||||
 | 
							for(var k in o){
 | 
				
			||||||
 | 
								res.push(k)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return res
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// now make these into real methods we can use from any object...
 | 
				
			||||||
 | 
						Object.prototype.keys = function(){ return Object.keys(this) }
 | 
				
			||||||
 | 
						Object.prototype.allKeys = function(){ return Object.allKeys(this) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b.keys()			// -> ['x']
 | 
				
			||||||
 | 
						b.allKeys()			// -> ['x', 'y', 'z']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// "Double" inheritance
 | 
					// "Double" inheritance
 | 
				
			||||||
// --------------------
 | 
					// --------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// There are actually three sources where JavaScript looks for attributes:
 | 
					// There are actually three sources where JavaScript looks for attributes:
 | 
				
			||||||
// 	1) the actual object
 | 
					// 	1) own attributes (local object) 
 | 
				
			||||||
// 	2) .__proto__ 
 | 
					// 	2) .__proto__ 
 | 
				
			||||||
// 		as coverd in the first section
 | 
					// 		as coverd in the first section
 | 
				
			||||||
// 	3) .constructor.prototype 
 | 
					// 	3) .constructor.prototype 
 | 
				
			||||||
// 		as explained in the previous section
 | 
					// 		as explained in the previous section
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Here is a basic inheritance structure (tree):
 | 
					// Though in the general case both .__proto__ and .constructor.prototype 
 | 
				
			||||||
 | 
					// point to the same object and are redundant, the two are independent 
 | 
				
			||||||
 | 
					// and can be used in parallel, thus the title.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Here is a basic inheritance structure (tree) with .__proto__ and 
 | 
				
			||||||
 | 
					// .constructor.prototype split to separate objects:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// 	O   A
 | 
					// 	O   A
 | 
				
			||||||
// 	 \ /
 | 
					// 	 \ /
 | 
				
			||||||
@ -242,7 +307,9 @@
 | 
				
			|||||||
		o: 0,
 | 
							o: 0,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function A(){}
 | 
						function A(){
 | 
				
			||||||
 | 
							//...
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	A.prototype.a = 1
 | 
						A.prototype.a = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var a = new A()
 | 
						var a = new A()
 | 
				
			||||||
@ -276,10 +343,13 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var a = {x: 1}
 | 
						var a = {x: 1}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var b = Object.create(a)
 | 
						var b = Object.create(a)
 | 
				
			||||||
	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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -287,7 +357,7 @@
 | 
				
			|||||||
// Creating an inheritance chain via the constructor mechanism is a bit
 | 
					// Creating an inheritance chain via the constructor mechanism is a bit
 | 
				
			||||||
// more involved, and there are multiple ways to do this...
 | 
					// more involved, and there are multiple ways to do this...
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Here we will create a similar chian:
 | 
					// Here we will create a similar chain to the above for comparison:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// 		C -> B -> A
 | 
					// 		C -> B -> A
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@ -326,6 +396,9 @@
 | 
				
			|||||||
	c instanceof A		// -> true
 | 
						c instanceof A		// -> true
 | 
				
			||||||
	c instanceof Object // -> true
 | 
						c instanceof Object // -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c instanceof function X(){} 
 | 
				
			||||||
 | 
											// -> false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This also works for manually created objects
 | 
					// This also works for manually created objects
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -366,6 +439,7 @@
 | 
				
			|||||||
	isInstanceOf(c, A)	// -> true
 | 
						isInstanceOf(c, A)	// -> true
 | 
				
			||||||
	isInstanceOf(c, Object)
 | 
						isInstanceOf(c, Object)
 | 
				
			||||||
						// -> true
 | 
											// -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isInstanceOf(c, function X(){})
 | 
						isInstanceOf(c, function X(){})
 | 
				
			||||||
						// -> false
 | 
											// -> false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -374,6 +448,9 @@
 | 
				
			|||||||
// Checking type (typeof)
 | 
					// Checking type (typeof)
 | 
				
			||||||
// ----------------------
 | 
					// ----------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// This section is mainly here for completeness and to address several
 | 
				
			||||||
 | 
					// gotcha's.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// What typeof returns in JavaScript is not too useful and sometimes 
 | 
					// What typeof returns in JavaScript is not too useful and sometimes 
 | 
				
			||||||
// even odd...
 | 
					// even odd...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -408,7 +485,7 @@
 | 
				
			|||||||
// Methods and the value of 'this'
 | 
					// Methods and the value of 'this'
 | 
				
			||||||
// -------------------------------
 | 
					// -------------------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// A method is simply an attribute that references a function.
 | 
					// A "method" is simply an attribute that references a function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 	function f(){
 | 
					 	function f(){
 | 
				
			||||||
		return this
 | 
							return this
 | 
				
			||||||
@ -422,9 +499,9 @@
 | 
				
			|||||||
// 'this' is a reserved word and is available in the context of a function
 | 
					// 'this' is a reserved word and is available in the context of a function
 | 
				
			||||||
// execution, not just in methods, but what value it references depends
 | 
					// execution, not just in methods, but what value it references depends
 | 
				
			||||||
// on how that function is called...
 | 
					// on how that function is called...
 | 
				
			||||||
// This is mostly useful and used in methods.
 | 
					// 'this' is mostly useful and used in methods.
 | 
				
			||||||
// 
 | 
					// 
 | 
				
			||||||
// A simple way to think about this is that 'this' always points to the 
 | 
					// A simple way to think about it is that 'this' always points to the 
 | 
				
			||||||
// "context" of the function call.
 | 
					// "context" of the function call.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// There are three distinct cases here:
 | 
					// There are three distinct cases here:
 | 
				
			||||||
@ -435,11 +512,12 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// 1) function call (implicit)
 | 
					// 1) function call (implicit)
 | 
				
			||||||
//	In the first case the context is either global/window/module which 
 | 
					//	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
 | 
					//	ever is the root context in a given implementation or undefined in
 | 
				
			||||||
//	strict mode
 | 
					//	ES5 strict mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f()					// -> window/global/module
 | 
						f()					// -> window/global/module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//	Strict mode example:
 | 
					//	Strict mode example:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
	function strict_f(){
 | 
						function strict_f(){
 | 
				
			||||||
@ -451,8 +529,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 2) new call (implicit)
 | 
					// 2) new call (implicit)
 | 
				
			||||||
// 	Here as we have discussed before, this is assigned a new object with
 | 
					// 	Here as we have discussed before, 'this' is assigned a new object 
 | 
				
			||||||
// 	some attributes set.
 | 
					// 	with some special attributes set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	new f()				// -> {}
 | 
						new f()				// -> {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -466,13 +544,14 @@
 | 
				
			|||||||
	o['f']()			// -> o
 | 
						o['f']()			// -> o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 	...or an explicitly passed to .call(..) / .apply(..) object
 | 
					// 	...or an explicitly passed to .call(..) / .apply(..) function methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f.call(o)			// -> o
 | 
						f.call(o)			// -> o
 | 
				
			||||||
	f.apply(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
 | 
					// ES5 also defines a third way to make method calls: Function.bind which
 | 
				
			||||||
 | 
					// creates a new function where 'this' is bound to the supplied object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var ff = f.bind(o)
 | 
						var ff = f.bind(o)
 | 
				
			||||||
	ff()				// -> o
 | 
						ff()				// -> o
 | 
				
			||||||
@ -480,7 +559,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NOTE: all of the above 5 calls are the same.
 | 
					// NOTE: all of the above 5 calls are the same.
 | 
				
			||||||
// NOTE: the resulting from .bind(..) function will ignore subsequent
 | 
					// NOTE: the resulting from .bind(..) function will ignore subsequent
 | 
				
			||||||
// 		.bind(..), .call(..) and .apply(..) method calls and this will 
 | 
					// 		.bind(..), .call(..) and .apply(..) method calls and 'this' will 
 | 
				
			||||||
// 		always be the original bound object.
 | 
					// 		always be the original bound object.
 | 
				
			||||||
// NOTE: the difference between strict and "quirks" modes is in the 
 | 
					// NOTE: the difference between strict and "quirks" modes is in the 
 | 
				
			||||||
// 		following:
 | 
					// 		following:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user