填坑-十万个为什么?(23)

273 阅读1分钟

简介:很多概念不清或忘记,重新构建自己的知识体系。每天问自己1~多个问题。我是菜鸟 成为大神之路!

1.Class 的基本语法 Link Class

生成实例对象的传统方法是通过构造函数

function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

//上面的代码用 ES6 的class改写,就是下面这样
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

事实上,类的所有方法都定义在类的prototype属性上面。

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

// 等同于
Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

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

class B {}
let b = new B();
b.constructor === B.prototype.constructor // true
`b是B类的实例,它的constructor方法就是B类原型的constructor方法。`

类的内部所有定义的方法,都是不可枚举的(non-enumerable)。

class Point {
  constructor(x, y) {
    // ...
  }
  toString() {
    // ...
  }
}
Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

`上面代码中,toString方法是Point类内部定义的方法,它是不可枚举的。这一点与 ES5 的行为不一致。`
var Point = function (x, y) {
  // ...
};
Point.prototype.toString = function() {
  // ...
};
Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]