对象与数据类型

JS中共有七种数据类型,除了ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。其余六种是:undefinednullBooleanStringNumberObject

undefined, number, string, boolean,null属于简单的值类型,使用基本类型变量可以调用方法是因为产生了包装对象(临时的),其中函数、数组、对象、new Number(10)等等都是对象,他们都是引用类型。

其中有几个需要注意的点:

  • 所有的对象都是由函数创建
  • 函数也是一个对象,由Function函数创建
  • Function也是一个对象,由它自己创建
  • 对于字面量创建的对象,只是使用函数创建对象的一个语法糖,例如
var obj = { a: 1, b: 2};
//等同于
var obj = new Object();
obj.a=1;
obj.b=2;

prototype__proto__

  • 可以通过Object.getPrototypeOf()Object.setPrototypeOf()访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性 __proto__
  • 所有函数对象具有prototype属性,普通对象没有,这个prototype的属性值是一个对象,默认的只有一个叫做constructor的属性,指向这个函数本身。
  • 所有的对象都有__proto__,指向创建它的函数的prototype(Object.prototype__proto__除外,它指向null),连同一个函数new出来的对象的__proto__都统一指向了这个函数的prototype,根据后面要讲述的原型链规则,也就是说通过这个函数new出来的所有对象都可以直接使用该函数原型上的任意属性和方法
  • 所有的函数,比如 function fn(){},都是由Function函数创建,因此fn的__proto__指向Functionprototype
  • Function也是函数,因此它也由Function创建的,也就是说它自己创建了自己!所有Function__proto__指向的就是Functionprototype
  • Object函数也是由Function创建,因此Object的__proto__同样指向Functionprototype
  • Object.prototype却是一个特例——它的__proto__指向的是null
  • prototype也是一个对象,原始prototype只有一个叫做constructor的属性,指向这个函数本身。因为prototype是一个对象,因此它也是由Object方法创建,因此它的__proto__将指向Object.prototype

ES6语法糖Class

Es6新增的一个Class只是一个prototype的语法糖

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

原型链

javaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

继承

关于这部分可以参考我的这篇文章Js实现继承的几种方式

ES6语法糖Class的继承

Es6的class实现继承可以使用extends

class ColorPoint extends Point {
  constructor() {
    super(); // 调用父类的constructor()
  }
}

super关键字,它在这里表示父类的构造函数,用来新建父类的this对象。

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

最简单明了的图