Mots clés : javascriptdynamic-languagesprototype-orientedjavascript
91
//Define a functional object to hold persons in JavaScript var Person = function(name) { this.name = name; }; //Add dynamically to the already defined object a new getter Person.prototype.getName = function() { return this.name; }; //Create a new object of type Person var john = new Person("John"); //Try the getter alert(john.getName()); //If now I modify person, also John gets the updates Person.prototype.sayMyName = function() { alert('Hello, my name is ' + this.getName()); }; //Call the new method on john john.sayMyName();
//Create a new object of type Customer by defining its constructor. It's not //related to Person for now. var Customer = function(name) { this.name = name; }; //Now I link the objects and to do so, we link the prototype of Customer to //a new instance of Person. The prototype is the base that will be used to //construct all new instances and also, will modify dynamically all already //constructed objects because in JavaScript objects retain a pointer to the //prototype Customer.prototype = new Person(); //Now I can call the methods of Person on the Customer, let's try, first //I need to create a Customer. var myCustomer = new Customer('Dream Inc.'); myCustomer.sayMyName(); //If I add new methods to Person, they will be added to Customer, but if I //add new methods to Customer they won't be added to Person. Example: Customer.prototype.setAmountDue = function(amountDue) { this.amountDue = amountDue; }; Customer.prototype.getAmountDue = function() { return this.amountDue; }; //Let's try: myCustomer.setAmountDue(2000); alert(myCustomer.getAmountDue());
var Person = function (name) { this.name = name; }; Person.prototype.getName = function () { return this.name; }; var john = new Person("John"); alert(john.getName()); Person.prototype.sayMyName = function () { alert('Hello, my name is ' + this.getName()); }; john.sayMyName(); var Customer = function (name) { this.name = name; }; Customer.prototype = new Person(); var myCustomer = new Customer('Dream Inc.'); myCustomer.sayMyName(); Customer.prototype.setAmountDue = function (amountDue) { this.amountDue = amountDue; }; Customer.prototype.getAmountDue = function () { return this.amountDue; }; myCustomer.setAmountDue(2000); alert(myCustomer.getAmountDue());
//The following statement generates an error. john.setAmountDue(1000);
84
function Child() {} function Parent() {} Parent.prototype.inheritedMethod = function () { return 'this is inherited' } function inherit(child, parent) { child.prototype = Object.create(parent.prototype) child.prototype.constructor = child return child; } Child = inherit(Child, Parent) const o = new Child console.log(o.inheritedMethod()) // 'this is inherited'
function Child() {} function Parent() {} Parent.prototype.inheritedMethod = function () { return 'this is inherited' } function inherit(child, parent) { function tmp() {} tmp.prototype = parent.prototype const proto = new tmp() proto.constructor = child child.prototype = proto return child } Child = inherit(Child, Parent) const o = new Child console.log(o.inheritedMethod()) // 'this is inherited'
class Parent { inheritedMethod() { return 'this is inherited' } } class Child extends Parent {} const o = new Child console.log(o.inheritedMethod()) // 'this is inherited'
76
function Person(name){ this.name = name; } Person.prototype.getName = function(){ console.log(this.name); } var person = new Person("George");
var person = {}; function Person(name){ this.name = name; } function getName(){ console.log(this.name); }
Person("George"); getName();//would print the "George" in the console
person.Person = Person; person.getName = getName;
person.Person("George"); person.getName();// -->"George"
Object {Person: function, getName: function, name: "George"}
person.__proto__.Person = Person; person.__proto__.getName = getName;
person.__proto__ = { Person: Person, getName: getName };
var propertiesObject = { Person: Person, getName: getName }; var person = Object.create(propertiesObject);
console.log(person.__proto__===propertiesObject); //true
Person.call(person, "George");
//apply is more useful when params count is not fixed Person.apply(person, ["George"]); getName.call(person); getName.apply(person);
function Person(name){ this.name = name; } my_person_prototype = { getName: function(){ console.log(this.name); } };
var newObject = {};
for(var key in my_person_prototype){ newObject[key] = my_person_prototype[key]; }
var newObject = Object.create(my_person_prototype); //here you can check out the __proto__ attribute console.log(newObject.__proto__ === my_person_prototype); //true //and also check if you have access to your desired properties console.log(typeof newObject.getName);//"function"
newObject.getName();
Person.call(newObject, "George");
Person.apply(newObject, ["George"]);
new FunctionName()
console.log(Object.prototype.__proto__===null);//true
61
var F = function() {} var f = new F()
f.__proto__ === F.prototype
f = Object.create(proto)
f.__proto__ === proto
var F = function(i) { this.i = i } var f = new F(1)
(Function) ( F ) (f)----->(1) | ^ | | ^ | i | | | | | | | | | | | | +-------------------------+ | | | |constructor | | | | | | | | +--------------+ | | | | | | | | | | | | | | | | | |[[Prototype]] |[[Prototype]] |prototype |constructor |[[Prototype]] | | | | | | | | | | | | | | | | | | +----------+ | | | | | | | | | | | | | | +-----------------------+ | | | | | | | | v | v v | v | (Function.prototype) (F.prototype) | | | | | | | |[[Prototype]] |[[Prototype]] [[Prototype]]| | | | | | | | +-------------------------------+ | | | | v v v (Object.prototype) (Number.prototype) | | ^ | | | | | +---------------------------+ | | | | +--------------+ | | | | | | | |[[Prototype]] |constructor |prototype | | | | | | | | -------------+ | | | v v | (null) (Object)
var f = new F(1)
f.constructor === F !f.hasOwnProperty('constructor') Object.getPrototypeOf(f) === F.prototype F.prototype.hasOwnProperty('constructor') F.prototype.constructor === f.constructor
class C { constructor(i) { this.i = i } inc() { return this.i + 1 } } class D extends C { constructor(i) { super(i) } inc2() { return this.i + 2 } }
// Inheritance syntax works as expected. c = new C(1) c.inc() === 2 (new D(1)).inc() === 2 (new D(1)).inc2() === 3
// "Classes" are just function objects. C.constructor === Function C.__proto__ === Function.prototype D.constructor === Function // D is a function "indirectly" through the chain. D.__proto__ === C D.__proto__.__proto__ === Function.prototype
// "extends" sets up the prototype chain so that base class // lookups will work as expected var d = new D(1) d.__proto__ === D.prototype D.prototype.__proto__ === C.prototype // This is what `d.inc` actually does. d.__proto__.__proto__.inc === C.prototype.inc
// Class variables // No ES6 syntax sugar apparently: // http://stackoverflow.com/questions/22528967/es6-class-variable-alternatives C.c = 1 C.c === 1 // Because `D.__proto__ === C`. D.c === 1 // Nothing makes this work. d.c === undefined
(c)----->(1) | i | | |[[Prototype]] | | v __proto__ (C)<--------------(D) (d) | | | | | | | | | |prototype |prototype |[[Prototype]] | | | | | | | | | | | +---------+ | | | | | | | | | | v v |[[Prototype]] (D.prototype)--------> (inc2 function object) | | | inc2 | | | | | |[[Prototype]] | | | | | | | | +--------------+ | | | | | | | v v | (C.prototype)------->(inc function object) | inc v Function.prototype
c = new C(1) c.inc() === 2
c.inc()
53
var obj = new Object(); obj.test = function() { alert('Hello?'); };
function obj() { } obj.prototype.test = function() { alert('Hello?'); }; var obj2 = new obj(); obj2.test();