What is __proto__


Here is an example of real world.

John has two sons, Tom and Tim. We need to register personal files for Tom and Tim. Since Tom and Tim have the same address, telephone number and last name as their father, we print "ditto to John" and then fill only their name and age. We are lazy ?!

This is __proto__. It saves memory. 

Lets see how __proto__ object affects our read and write.

__proto__ should be treated as "read-only". However, we can assigne any object to __proto__. (At least for the present version of Flash MX) . It is good to understand it by assign desired object to __proto__.

We should test movie and view debug- list variables to understand the result of read and write.

READ

To peek the address of Tom, we first search it in the file of Tom himself. We did not fount it. So we search the file of John because of "ditto". OK, we find the address.

To peek the Last name of Tom, we search it in the file of Tom and then John. No last name is found there but we see a note: ditto to Paul". Paul is the father of John. So we search last name in the file of John's father (the grandFather of Tom), and we find it there.

A={x:3,y:4}
B={z:5};
B.__proto__=A;
C={u:6}
C.__proto__=B;

trace(C.z);// output 5.
trace(C.x);// output 3.

__proto__ is a chain. Here, C.__proto__.__proto__ is A;

When we need to read a property, local is searched. If there is no such property,it will search the property through __proto__ chain. Becareful when we say "not found", it is different from "found to be undefined".

A={x:5}
B={x:undefined}
B.__proto__=A;
trace(B.x);// output: undefined. It will not do search in the __proto__ chain.

WRITE

Tom wants to update his address. So, we fill the field of "address" in Tom's file. (Of-course, we should not change the address of John);

In real world, we might check whether the new address is the same as the old address. If they are not the same, it means Tom has moved, so we fill the address. If they are the same, we dont do anything.

Action script does not check this. Any assignment will be written to local.

A={x:5}
B={}
B.__proto__=A;

First we do several test:

B.x=7;

This will create x:7 at local part of B. Nothing is changed to A;

B.x=B.x;

First it reads what is B.x and get x to be 5 through __proto__ chain. Then it assign 5 to B.x. This is an updating process. So it create x:5 in local of B. It never minds whether the values are the same as before or not.

B.x++;

It finds x to be 5 through __proto__ chain and then increase it by 1, then write to local to create x:6 in B. The A.x is still the same to be 5;

That script is implemented as "B.x=B.x+1"; (This might surprise C language programmer.)

Method in __proto__ and what is "this" 

Here is an example for calling method through __proto__

A={    x:10,
    
      inc:function(){this.x++;}
}
B={x:5}
B.__proto__=A;
C={};
C.__proto__=B;
C.inc();

Here, the inc() method is search through __proto__ chain and found in A. When the method is executed, it search through __proto__ chain for x , and found it in B. The value is increased by one and wirtten to C; 

It seems confusing, right ? It execute the function in B and read the data in A then write the result to C.

Please note, Although inc method is created at A, it is the C object that calls through __proto__. So when we meat this.x , it is C.x  not A.x; 

Is it READ or WRITE when property stores the reference of an object or array ?

OK, till now, we are discussing READ and WRIT about property that stores a primitive value. How about a property storing object reference ? 

You get to know the diffence between "object reference" and "object contents". You get to know the operation we do is going to change the reference or the contents.

In real world:

1. Tom want to update a new information about his teacher Jack. Jack bought a new car, got married and moved to a new address.

In fact. We did "READ" the file to get the name of the teacher. We update some data to the file of Jack. Nothing is changed in Tom's file.

This is an update about "object content".

2. Tim want to update a new information about his teacher. His new teacher Mary replaced Jack. 

Well, this is really an updating of "object reference". We get to updat the file of Tim. We fill "Mary" as teacher's name in Tim's file.

Examples:

A={arr:[0,1,2]}
B={};
B.__proto__=A;
B.arr.push(3);
B.arr=B.arr.concat([7]);

"B.arr.push(3);" try to find out what is B.arr; Through __proto__ chain, tIt is found in A to be an Array. It find the array and push a value (3) to it. The result is an array of [0,1,2,3];

While "B.arr=B.arr.concat([7]);" will try to return a new Array by concat() function. This is a  chang of reference, so it is stored to B; Here is an array in local of B: [0,1,2,3,7];  There is still an array in A contains [0,1,2,3];


DELETE

A={x:5}
B={x:6}
B.__proto__=A;
delete B.x
trace(B.x);

"Delete" is a process of "WRITE". So, delete only affects local. Here we delete B.x, so B lost the property of x in the local. However, when we try to access B.x, we get x=5 through __proto__ chain to access x in A; To disable the x property we should set B.x=null instead of delete B.x;

If we do delete B.x once more will it delete A.x through __proto__ chain ? 

NO ! Writing process only affects local. The __proto__ object is read only to B.

Please note: delete B.x is completely different from setting B.x=undefined or setting B.x=null; The later commands still setting a property x. Flash only search through __proto__ chain when there is no such property. If there is such property, even it is null, it reports null. 


Other discussion about __proto__

1.
That rule seems true for Custom functions and object. Is that rule also true for building function and building object of Flash ?

Answers: Not necessary:

pt1={x:300,y:400}
pt2={};
pt2.__proto__=pt1;
mc.globalToLocal(pt2);
//see debug list variable
trace(pt2.x);

We can access pt2.x through __proto__, but the building function "globalToLocal" does not.

d=new Date();
d2={};
d2.__proto__=d;
trace(d2.getMonth());

No, we can not access all the properties in Date object.


2. 
Can I use __proto__ to copy an object ?

Many function, e.g globalToLoacl(point), when we pass the object as parameter, it is pass as reference and the contents of the object are changed permanently. In some occasion, we would like to preserve the original one. So, we need a copy to feed the parameter of this function. To create a copy of object, we needs to manually create each property and assign the same value to that new object. Can we use __proto__ ? 

Yes, it is handy.

However, we should note that, if one of our property containg reference of object, we need to "fine tune" our copy. Do we need an independent array in our copy object ? or the copy object just share that same array ?

The second cautions is: Building function does not necessarily support __proto__;

function doubling(pt){
pt.x*=2;
pt.y*=2;
}
pt1={x:300,y:400}
pt2={};
pt2.__proto__=pt1;
doubling(pt2);

2.
Modifying the __proto__ object. 

B.__proto__=A; What will happens if we modify A ?

Tom's personal file is ditto to John. What will happen if we change the address of John ? Well, it will possibly cause unpredictable troubles. If Tom and John both moved to a same address, then it is handy that we just change the address of John and Tom's remains ditto to John.

If only John  moves, then change the address of John will affect Tom. The "ditto" thing will cause troubles. If Tom already gets the address filled in his file, then that it does not matter what is John's address.

For a complex script, it is difficult to know what properties have been updated to local of B and what properties have not.

Usually we do not change A once B is created. If we need change, change of A should be limited in "adding" some properties not modifying existing properties.