只要你开始思考、开始行动,你就已经走上了一条必然不易,但也充满希望的路途了。
     
   
今日学习内容 1、JS 红皮书 P254-256 第八章:对象、类与面向对象编程
今日笔记 1、类的语法可以非常方便地定义应该存在于实例上的成员、应该存在于原型上的成员,以及应该存在于类本身的成员。
实例成员: 每次通过 new 调用类标识符时,都会执行类构造函数。在这个函数内部,可以为新创建的实例(this)添加“自有”属性。至于添加什么样的属性,则没有限制。另外,在构造函数执行完毕后,仍然可以给实例继续添加新成员。每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享: 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class  Person  {  constructor (               this .name  = new  String ("Jack" );     this .sayName  = () =>  console .log (this .name );     this .nicknames  = ["Jake" , "J-Dog" ];   } } let  p1 = new  Person (),  p2 = new  Person (); p1.sayName ();  p2.sayName ();  console .log (p1.name  === p2.name ); console .log (p1.sayName  === p2.sayName ); console .log (p1.nicknames  === p2.nicknames ); p1.name  = p1.nicknames [0 ]; p2.name  = p2.nicknames [1 ]; p1.sayName ();  p2.sayName ();  
原型方法与访问器: 为了在实例间共享方法,类定义语法把在类块中定义的方法作为原型方法。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class  Person  {  constructor (          this .locate  = () =>  console .log ("instance" );   }      locate (     console .log ("prototype" );   } } let  p = new  Person ();p.locate ();  Person .prototype locate (); class  Person  {  name : "Jake" ; } const  symbolKey = Symbol ("symbolKey" );class  Person  {  stringKey (     console .log ("invoked stringKey" );   }   [symbolKey]() {     console .log ("invoked symbolKey" );   }   ["computed"  + "Key" ]() {     console .log ("invoked computedKey" );   } } let  p = new  Person ();p.stringKey ();  p[symbolKey]();  p.computedKey ();  class  Person  {  set  name (newName ) {     this .name_  = newName;   }   get  name () {     return  this .name_ ;   } } let  p = new  Person ();p.name  = "Jake" ; console .log (p.name ); 
静态类方法: 可以在类上定义静态方法。这些方法通常用于执行不特定于实例的操作,也不要求存在类的实例。与原型成员类似,静态成员每个类上只能有一个。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class  Person  {  constructor (          this .locate  = () =>  console .log ("instance" , this );   }      locate (     console .log ("prototype" , this );   }      static  locate (     console .log ("class" , this );   } } let  p = new  Person ();p.locate ();  Person .prototype locate (); Person .locate (); class  Person  {  constructor (age ) {     this .age_  = age;   }   sayAge (     console .log (this .age_ );   }   static  create (          return  new  Person (Math .floor (Math .random () * 100 ));   } } console .log (Person .create ()); 
非函数原型和类成员: 虽然类定义并不显式支持在原型或类上添加成员数据,但在类定义外部,可以手动添加: 
 
1 2 3 4 5 6 7 8 9 10 11 class  Person  {  sayName (     console .log (`${Person.greeting}  ${this .name} ` );   }  }  Person .greeting  = 'My name is' ;Person .prototype name  = 'Jake' ; let  p = new  Person (); p.sayName ();  
注意 类定义中之所以没有显式支持添加数据成员,是因为在共享目标(原型和类)上添加可变(可修改)数据成员是一种反模式。一般来说,对象实例应该独自拥有通过 this引用的数据。