[重要]区分JS中的对象和实例以及new操作符和Object.create()的实现

259 阅读2分钟

在阅读《JavaScript高级程序设计》(第四版)中,我发现一个非常重要的问题。

就是在理解ES5使用Object.create实现单继承中

new 和 Object.create() 的区别

引入MDN对这两者的解释

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的 __proto __


先看代码

// 这里我创建了一个构造函数(规范:构造函数首字母大写)
// 同时给这个对象类型定义了name
function Base(){
    this.name = "Jun"
}

// 在这一步,我通过new操作符,创建了一个实例,这个实例是一个对象
let obj = new Base();

定义:通过new操作符创建出来的对象称作实例

在JavaScript世界中,万物皆对象,而通过new出来的对象,对其称呼为实例。

Object.create()主要用于实现JavaScript的继承,还有就是用于继承于某个实例

new操作符创建对象的实现步骤:

  1. 创建一个空的简单JavaScript对象(即{})。
  2. 链接该对象(设置该对象的constructor和prototype)到 被new的对象;
  3. 将步骤1新创建的对象作为this的上下文 ;

Object.create()的简单内部实现:

function create(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

实例是无法通过new操作符去创造新的实例,但是可以通过Object.create()方法去创造一个继承与实例的实例。当然,不推荐这么做!

JavaScript里面除了原始值,其余全部都是对象。在上述例子中,Base作为构造器,其实本身也是对象。也可以为它添加属性,但这并没有意义,还会造成代码混乱。所以编写代码请注意规范

目前开发网站基本规模都比较大,强烈推荐读者去学习TypeScript,拥抱未来。


扩展:

JavaScript本身是没有类这个概念的,包括后来推出的ES6也只是语法糖。

如果要实现类的概念,就必须使用原型链的力量。

请使用ES6的class操作符,不要再自行实现继承!