Created
May 13, 2012 04:23
-
-
Save rauschma/2680473 to your computer and use it in GitHub Desktop.
Class declarations with object exemplar semantics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----- Example code: | |
// Class declarations: | |
// - No data properties allowed | |
// - Future: support mixins | |
// - Optional: call the initialization method `new` instead of `constructor` | |
// Superclass | |
class Person { | |
constructor(name) { | |
this.name = name; | |
} | |
describe() { | |
return "Person called "+this.name; | |
} | |
} | |
// Subclass | |
class Employee extends Person { | |
constructor(name, title) { | |
super.constructor(name); | |
this.title = title; | |
} | |
describe() { | |
return super.describe()+" ("+this.title+")"; | |
} | |
}); | |
var jane = new Employee("Jane", "CTO"); | |
console.log(jane instanceof Person); // true | |
//----- Desugars to: | |
// Advantages: | |
// - You can always write Person.* instead of Person.prototype.* | |
// - Subtyping becomes very easy | |
// More information: http://www.2ality.com/2011/06/prototypes-as-classes.html | |
var Person = { | |
constructor: function (name) { | |
this.name = name; | |
}, | |
describe: function() { | |
return "Person called "+this.name; | |
} | |
}; | |
var Employee = Object.create(Person); | |
Employee.constructor = function (name, title) { | |
Employee.super.constructor.call(this, name); | |
this.title = title; | |
}; | |
Employee.describe = function () { | |
return Employee.super.describe.call(this)+" ("+this.title+")"; | |
}; | |
var jane = Object.create(Employee); | |
jane.constructor("Jane", "CTO"); | |
console.log(Person.isPrototypeOf(jane)); | |
//----- Same functionality, via the library Proto.js, https://github.com/rauschma/proto-js | |
var Person = Proto.extend({ | |
constructor: function (name) { | |
this.name = name; | |
}, | |
describe: function() { | |
return "Person called "+this.name; | |
} | |
}); | |
var Employee = Person.extend({ | |
constructor: function (name, title) { | |
Employee.super.constructor.call(this, name); | |
this.title = title; | |
}, | |
describe: function () { | |
return Employee.super.describe.call(this)+" ("+this.title+")"; | |
} | |
}); | |
var jane = Employee.new("Jane", "CTO"); | |
console.log(Person.isPrototypeOf(jane)); | |
//----- Compatibility with (legacy) constructor functions | |
// - To extend a constructor function Foo, you write: `extends Foo.prototype` | |
// Could be handled automatically, by checking whether the operand of `extends` is a function. | |
// Proto.js comes with support for extending constructor functions. |
As for constructor properties (static properties): Those are used in Java to simulate first-class functions and in JavaScript to simulate namespaces. Hence, with ECMAScript.next having modules, there will be much less use for them. For object exemplars, there is no difference between prototype properties and static properties.
:) thank you for your answer(s).
"their names are only visible to themselves, not anywhere else."
But i can test like this :
jane.constructor.name
//or :
jane.__proto__
// and (i know, not very nice)
Object.prototype.getTypeName = function () { return this.constructor.name; }
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You are using named function expressions. Note that their names are only visible to themselves, not anywhere else.
What you can do is define a constructor function in a manner that looks almost like the code above:
In this case, Person is an old-school constructor function, with all associated complications (e.g. subtyping being a bit tricky). That is roughly how the proposed maximally minimal class declarations [1] for ECMAScript.next work.
[1] http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes