Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6标准入门(二) #26

Open
plh97 opened this issue Apr 14, 2018 · 0 comments
Open

ES6标准入门(二) #26

plh97 opened this issue Apr 14, 2018 · 0 comments
Assignees
Labels
javaScript 关于js的一些事 博客 写一些前端技术记录 学习 如果不学习,那今天和昨天又有什么区别 看书 其实如果不看书的话,那么每天写的东西都和昨天一样,又有什么意思

Comments

@plh97
Copy link
Owner

plh97 commented Apr 14, 2018

第18章 class Class基本语法

JavaScript语言的传统方法是通过构造函数定义并生成新对象。下面举个例子。

  this.x = x;
  this.y = y;
Point.prototype.toString = function(){
  return `(${this.x} , ${this.y})`
}

上面这种写法和Java,c++区别很大,这让程序员很困惑。
es6提供了新的语法糖ckass

class Point{
  constructor(x,y){
    this.x = x;
    this.y = y;
  }
  toString(){
    return `(${this.x} , ${this.y})`
  }
}

constructor是构造器的方法。而this则代表了该对象。class就是es5的构造函数的另一种写法。更加语义化。

class Point{}
Point === Point.prototype.constructor.Point   //true

下面写法也是对等的

class Point {
  constructor() {
    // ...
  }
  toString() {
    // ...
  }
  toValue() {
    // ...
  }
}
Point.prototype = {
	constructor(){}
	toString(){}
	toValue(){}
}

而在类的实例上面调用方法,其实就算调用原型上面的方法。

class B{}
let b = new B();

这些方法都是不可枚举的.通过class内部命名的方法,和通过prototype命名的方法最大的不同是一个是可枚举的,另一个是不可枚举的。而添加static关键字的方法会被添加到Point的原型,因此仅仅只可以内部使用。

class Point {
  constructor() {
    // ...
  }
  static toString() {
    // ...
  }
  toValue() {
    // ...
  }
}
class Point1 {}
Point1.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};
const p = new Point();
const p1 = new Point1();
console.log(Object.keys(Point.prototype));
console.log(Object.keys(Point1.prototype));
console.log(p);
console.log(p1);
console.log(Point.prototype.constructor === Point);      // true
console.log(Point1.prototype.constructor === Point1);      // true
console.log(Point1.prototype.constructor == Point1);      // true  

image
其中虚的是不可枚举的。

constructor 方法

这个方法是默认存在的方法,,通过new命令生成对象实例时候自动调用的方法,默认返回它本身这个实例化对象this,当然可以指定返回其他对象。

实例对象

生成实例对象和es5一样,如果没有new命令,则会报错,除非你在他前面添加static 作为静态方法,就可以。下面可以看到,constructor里面的x,y, 静态aa方法,普通bb方法

class Point {
  constructor() {
    // ...
    this.x = 1;
    this.y = 1;
  }
  static aa() {}
  bb() {}
}
const p = new Point();
console.log(p);
console.log(Object.keys(Point.prototype));

image

但是当aa,bb都是普通方法的时候,又是另一个样子,奇了个葩

image

不存在的变量提升hoist,他这个和es5的函数提升完全不一样

new Foo(); // referenceError: Me is not defined
class Foo{};

class 的继承

class Foo exntend foo {}
下面介绍super()

class Point {
  constructor() {
    this.x = 1;
    this.y = 1;
  }
  getname() {
    return this.name;
  }
}
class ColorPoint extends Point {
  constructor() {
    super();
    this.name = 'ColorPoint';
  }
  aaa() {
    return 'ColorPoint';
  }
}
const p = new ColorPoint();
console.log(p);

image
这里ColorPoint存在两条原型链,一条是继承方法,另一条是继承constructor里面定义的变量。
下面由3钟继承的特殊情况

  • 第一种,子类继承Object
    class A extends Object {}
    其实就算对Object的复制
  • 第二种不继承
    class A{}
    其实就是默认继承Function。
  • 第三种继承null
    class A extends null{}
    真正的不继承任何东西

super 关键字

他代表了父类的实例。

class类中的getter和setter

class Point {
  constructor() {
    this.x = 1;
    this.y = 1;
    this.name = 'pengliheng';
  }
  getname() {
    return this.name;
  }
  get prop() {
    return this.name;
  }
  set prop(value) {
    console.log(`setter: ${value}`);
  }
}
const p = new Point();
p.prop;                             // setter: pengliheng
p.prop = 'hhhah';            
p.prop;                            //  setter: hhhah

定义一个属于自己的Array,不要再原生Array上面扩展方法,如果需要,请看下面代码

class VersionArray extends Array {
  constructor() {
    super();
    this.history=[[]];
  }
  commit() {
    this.history.push(this.slice());
  }
  revert(){
    this.splice
  }
}

18.5 class 的 静态方法

const a = 'test';
const b = 'test';
a===b // true

const a = {};
const b = {};
a===b // false

const a = [];
const b = [];
a===b // false
[] === []  //false

const a = [];
const b = a;
a===b // true    ,为什么呢? 因为point   ,a point b

下面看一下他们为什么不相等

class Point {
  constructor() {
    this.x = 1;
    this.y = 1;
    this.name = 'pengliheng';
  }
  static getname() {
    return this.name;
  }
  getTName() {
    console.log(new Point() === this);
  }
}
console.log(Point.getname());     // 静态方法,不需要实例化就能获取
const p = new Point();
p.getTName();                             // false,{} !== {},即便是同样的对象,他们也互不相等。     普通方法需要实例化。

静态属性

19章装饰器

装饰器是一种表达式,他能对类的行为发生改变,,这种改变发生在编译阶段,
有点超前,自己去了解吧,如果你不是用的react或者经常用class面向对象编程,并且需要继承属性的时候,你都用不到装饰器。

20章module,这个以后再说,书里面没有提到module模块化的原理,如何引入的。没有讲的深入。

21章编程风格(关于es5过度到es6的使用建议)

####使用 let / constant 替代 var
由于模块化默认使用'use strit'严格模式
所以以后应该是严格模式默认的。
使用优先级
const>let>var
const 的使用是因为他是常量,能够给人直观的,如果你要改变常量,建议去定义一个新的常量。这也是函数式编程风格所要求的。
坚持遵循 先声明,再使用的编程规范。

####使用模板字符串添加变量
使用单引号

// bad
const a = '<div>'+value+'</div>'
// good   更具语义化
const a = `<div>${value}</div>`

解构变量

// bad
var a = 1,b=2,c=3;
//good
const a = 1;
const b = 2;
const c = 3;
// best,,,,,更具语义化。
const [a,b,c] = [1,2,3];

image

对象

熟悉typescript的你可能知道,它推崇的是尽量使用常量,以及变量+类型
声明了一个对象,尽量不要去改变它,如果真的要改变它,建议使用以下

// bad
const a = {};
a.x = 3;
// 

使用...扩展符号来复制数组

var a = [...arr];
var b = Array.from(arr);

箭头函数 => 推荐使用,

他消灭了 绑定 bind

推荐使用class来命名对象

使用Eslint代码检查工具。。。

统一规范编程风格,

结束语,不写了。烂书越写越烦。
@plh97 plh97 self-assigned this Apr 14, 2018
@plh97 plh97 added 学习 如果不学习,那今天和昨天又有什么区别 博客 写一些前端技术记录 javaScript 关于js的一些事 看书 其实如果不看书的话,那么每天写的东西都和昨天一样,又有什么意思 labels Apr 14, 2018
@plh97 plh97 changed the title ES6标准入门 - 阅读笔记(二) ES6标准入门----阅读笔记(二) May 25, 2018
@plh97 plh97 changed the title ES6标准入门----阅读笔记(二) ES6标准入门(二) May 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
javaScript 关于js的一些事 博客 写一些前端技术记录 学习 如果不学习,那今天和昨天又有什么区别 看书 其实如果不看书的话,那么每天写的东西都和昨天一样,又有什么意思
Projects
None yet
Development

No branches or pull requests

1 participant