-
Notifications
You must be signed in to change notification settings - Fork 35
Prototype
All the properties belonging to an object will be available to another object, if the object is the prototype of the latter.
object A object B
+- a: 10 +- prototype: object A
A.a == 10 // true
B.a == 10 // true
The property 'a' does not exist in B, but it is also available to B since A is prototype of B.
An object can be prototype of another object, even this object has also its prototype, that is prototype chain.
object A object B object C object D
+- a: 10 +- prototype: A +- prototype: B +- prototype: C
When a property of object to be accessed, ReoScript run-time will firstly find the property in its owner object, if not found, then find it in its prototype, and so on, until there is no prototype anymore.
console.log(A.a + ' ' + B.a + ' ' + C.a + ' ' + D.a);
The output is:
10 10 10 10
If we do B.a = 20
, the result will be:
10 20 20 20
When a function to be defined, the prototype object of this function will also be created automatically. For example:
function User() {
}
console.log(User.prototype);
The output is:
[object Object]
Notice that User.prototype
is not of type User
, it is just a normal object.
debug.assert(User.prototype instanceof User); // false
debug.assert(User.prototype instanceof Object); // true
Built-in constructor such as Array has also 'prototype' property so typically we could use it to extend for Array:
Array.prototype.add = function(element) {
this.push(element);
};
var arr = new Array();
arr.push(1);
arr.add(2); // 'add' redirect to 'push'
console.log(arr);
The output is:
[1, 2]
A constructor is physically a normal function. Usually we called it Constructor and keep the first letter of its name to be capitalized in order to specify that it will be used to create new object instance.
function User() {
console.log('user invoked');
}
Function to be called using new keyword will create a new object instance.
User() // function call
new User // create instance before function call
new User(a, b) // create instance with arguments before function call
The all of lines above are valid syntax to use a function, but notice that they does different things.
The code below typically be used to create instance of a constructor.
var usr1 = new User();
When this to be executed, ReoScript run-time performs the following actions:
- Create an new object instance
- Set prototype of usr1 to User.prototype
- Set this keyword to usr1
- Call 'User' function, pass this and arguments
When a function called by new keyword, the this will point to the instance itself. For example:
function User() {
this.name = 'guest';
}
var usr1 = new User();
console.log(usr1.name);
The output is:
guest
Constructor is a function, used to create a new instance. Constructor is not a prototype to any instances, Constructor has a property called prototype
, that is the prototype to any instances. The property prototype
of Constructor be created when a constructor has declared.
function Apple() {
}
debug.assert(Apple.prototype != null); // true
When an instance be created from a constructor, the prototype to the instance will be prototype of the constructor. System keeps the prototype of instance in system property __proto__
.
function Apple() {
}
var obj = new Apple();
debug.assert(obj.__proto__ === Apple.prototype); // true
When we accessing a property from obj
but the property does not exist in obj
, ReoScript interpreter will trying to find the property from obj.__proto__
, if not found, then obj.__proto__.__proto__
, etc...
Constructor is function, but prototype is object, all instances from a constructor has a same prototype object.