Javascript's prototypal inheritance can be tough to wrap you head around, but I think an easy way to think about prototype and __proto__ is the following:
When you create a new object you would say
var bob = new WorkerBee();
given the following definition of WorkerBee as
function WorkerBee (projs) {
this.projects = projs || [];
}
WorkerBee.prototype = new Employee;
function Employee (name, dept) {
this.name = name || "";
this.dept = dept || "general";
}
When you see the above code you may think what would happen if you forgot to instantiate a new Employee when you set WorkerBee's prototype.
aka WorkerBee.prototype = Employee;
Well lets try it out, first off you will see that you can no longer access variables set in Employees constructor
so bob.name or dept will be undefined
also you will notice that bob will not be an instanceof Employee anymore since you broke the inheritance chain by not saying new Employee
Some Notes are below to convince your self further of your understanding of prototype and __proto__.
function Ninja(){}
Ninja.prototype.swingSword = function(){
return true;
};
var ninjaA = Ninja();
assert( !ninjaA, "Is undefined, not an instance of Ninja." );
var ninjaB = new Ninja();
assert( ninjaB.swingSword(), "Method exists and is callable." );
http://ejohn.org/apps/learn/#65
var ninja = (function(){
function Ninja(){}
return new Ninja();
})();
// Make another instance of Ninja
var ninjaB = new ninja.constructor();
assert( ninja.constructor == ninjaB.constructor, "The ninjas come from the same source." );
http://ejohn.org/apps/learn/#74
Quick test of prototypes
car instanceof Vehicle
false
Vehicle.prototype.isPrototypeOf(car);
false
Car.prototype = new Vehicle;
Vehicle
Vehicle.prototype.isPrototypeOf(car);
false
car instanceof Vehicle
false
car = new Car;
Car
Vehicle.prototype.isPrototypeOf(car);
true
car instanceof Vehicle
true
-------------
function Blah() {}
> Blah.prototype
Blah
> Blah.prototype.constructor
function Blah() {}
> Blah.prototype.constructor.__proto__
function Empty() {}
> Blah.prototype.constructor.__proto__.constructor
function Function() { [native code] }
> Blah.prototype.constructor.__proto__.constructor.prototype
function Empty() {}
> Blah.prototype.constructor.__proto__.constructor.prototype.constructor.prototype
function Empty() {}
http://i.imgur.com/IkxPv.png
http://stackoverflow.com/questions/650764/how-does-proto-differ-from-constructor-prototype
http://www.klauskomenda.com/code/javascript-inheritance-by-example/
Determining instance relationships
Property lookup in JavaScript looks within an object's own properties and, if the property name is not found, it looks within the special object property
__proto__
. This continues recursively; the process is called "lookup in the prototype chain".
The special property
__proto__
is set when an object is constructed; it is set to the value of the constructor's prototype
property. So the expression new Foo()
creates an object with __proto__ == Foo.prototype
. Consequently, changes to the properties of Foo.prototype
alters the property lookup for all objects that were created bynew Foo()
.
Every object has a
__proto__
object property (except Object
); every function has a prototype
object property. So objects can be related by 'prototype inheritance' to other objects. You can test for inheritance by comparing an object's __proto__
to a function's prototype
object. JavaScript provides a shortcut: the instanceof
operator tests an object against a function and returns true if the object inherits from the function prototype. For example,
1
2
| var f = new Foo(); var isTrue = (f instanceof Foo); |
For a more detailed example, suppose you have the same set of definitions shown in Inheriting Properties. Create an
Engineer
object as follows:
1
| var chris = new Engineer( "Pigman, Chris" , [ "jsd" ], "fiji" ); |
With this object, the following statements are all true:
1
2
3
4
5
| chris.__proto__ == Engineer.prototype; chris.__proto__.__proto__ == WorkerBee.prototype; chris.__proto__.__proto__.__proto__ == Employee.prototype; chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype; chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null ; |
Given this, you could write an
instanceOf
function as follows:
1
2
3
4
5
6
7
8
9
10
11
| function instanceOf(object, constructor) { while (object != null ) { if (object == constructor.prototype) return true ; if ( typeof object == 'xml' ) { return constructor.prototype == XML.prototype; } object = object.__proto__; } return false ; } |
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model
No comments:
Post a Comment