ES5

ES5类与继承-原型链

  1. function Foo(name) {
  2. this.name = name;
  3. }
  4. Foo.prototype.myName = function() {
  5. return this.name;
  6. };
  7. function Bar(name,label) {
  8. Foo.call( this, name );
  9. this.label = label;
  10. }
  11. // here, we make a new `Bar.prototype`
  12. // linked to `Foo.prototype`
  13. Bar.prototype = Object.create( Foo.prototype );
  14. // Beware! Now `Bar.prototype.constructor` is gone,
  15. // and might need to be manually "fixed" if you're
  16. // in the habit of relying on such properties!
  17. Bar.prototype.myLabel = function() {
  18. return this.label;
  19. };
  20. var a = new Bar( "a", "obj a" );
  21. a.myName(); // "a"
  22. a.myLabel(); // "obj a"

ES5类与继承-构造函数

  1. function Parent(name){
  2. this.value = "value";
  3. this.name = name;
  4. }
  5. function Child(name, age){
  6. Parent.apply(this, [name]);
  7. this.age = age;
  8. }
  9. const c = new Child("Name", 11);
  10. c.name // "Name"
  11. c.age // 11
  12. c.value // "Value"

ES6

ES6的类与继承

  1. class Widget {
  2. constructor(width,height) {
  3. this.width = width || 50;
  4. this.height = height || 50;
  5. this.$elem = null;
  6. }
  7. render($where){
  8. if (this.$elem) {
  9. this.$elem.css( {
  10. width: this.width + "px",
  11. height: this.height + "px"
  12. } ).appendTo( $where );
  13. }
  14. }
  15. }
  16. class Button extends Widget {
  17. constructor(width,height,label) {
  18. super( width, height );
  19. this.label = label || "Default";
  20. this.$elem = $( "<button>" ).text( this.label );
  21. }
  22. render($where) {
  23. super.render( $where );
  24. this.$elem.click( this.onClick.bind( this ) );
  25. }
  26. onClick(evt) {
  27. console.log( "Button '" + this.label + "' clicked!" );
  28. }
  29. }

ES6所解决的问题

https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/apA.md

Beyond this syntax looking nicer, what problems does ES6 solve?

  1. There’s no more (well, sorta, see below!) references to .prototype cluttering the code.
  2. Button is declared directly to “inherit from” (aka extends) Widget, instead of needing to use Object.create(..) to replace a .prototype object that’s linked, or having to set with .__proto__ or Object.setPrototypeOf(..).
  3. super(..) now gives us a very helpful relative polymorphism capability, so that any method at one level of the chain can refer relatively one level up the chain to a method of the same name. This includes a solution to the note from Chapter 4 about the weirdness of constructors not belonging to their class, and so being unrelated — super() works inside constructors exactly as you’d expect.
  4. class literal syntax has no affordance for specifying properties (only methods). This might seem limiting to some, but it’s expected that the vast majority of cases where a property (state) exists elsewhere but the end-chain “instances”, this is usually a mistake and surprising (as it’s state that’s implicitly “shared” among all “instances”). So, one could say the class syntax is protecting you from mistakes.
  5. extends lets you extend even built-in object (sub)types, like Array or RegExp, in a very natural way. Doing so without class .. extends has long been an exceedingly complex and frustrating task, one that only the most adept of framework authors have ever been able to accurately tackle. Now, it will be rather trivial!
  1. 更简洁的代码
  2. 不需要再用 Object.create() 或者设置 .__proto__ Object.setProtytoyeOf() 来写继承
  3. 相对多态,可以访问父类子类同名方法,解决了 constructor 不属于该类的的问题
  4. 防止出错,防止属性暗中共享
  5. 可以继承build-in object( Array RegExp