04-原型、原型链、继承

112 阅读2分钟

简单的基础就不多说了,主要记录一些容易搞混的地方和实现原理,现在都用class了,可以深入了解一下原理。

var num = 1,
  str = '1',
  flag = true,
  arr = [],
  obj = {},
  fn = function () {};

console.log(num.__proto__ === Number.prototype);
console.log(str.__proto__ === String.prototype);
console.log(flag.__proto__ === Boolean.prototype);
console.log(arr.__proto__ === Array.prototype);
console.log(obj.__proto__ === Object.prototype);
console.log(fn.__proto__ === Function.prototype);

console.log(fn.__proto__.__proto__ === Object.prototype); // 难点1
console.log(Function.__proto__ === Function.prototype); // 难点2

new 操作符

理解原型链之前,要理解new做了什么

  1. 在内存中创建一个新的对象(空对象);

  2. 这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性;(原型链重点)

  3. 构造函数内部的this,会指向创建出来的新对象;

  4. 执行函数的内部代码(函数体代码);

  5. 如果构造函数没有返回非空对象,则返回创建出来的新对象;

对象的隐式原型[[prototype]]

获取方式
1、__ proto__ (不推荐开发中使用)
2、Object.getPrototypeOf()

函数的原型

获取方式

function foo () {}
foo.prototype

// 注意:箭头函数没有显式原型,所以不能作为构造函数被new
const bar = () => {}
bar.prototype  // undefined

继承实现

function createObject(proto) {
  function Fn() {}
  Fn.prototype = proto;
  return new Fn();
}

function inheritPrototype(subType, superType) {
  // 原型继承   *不要直接赋值,否则引用类型指向同一个对象
  subType.prototype = createObject(superType.prototype); // 可以用Object.create()替代
  // 还原子类构造函数,否则是父类的constructor
  Object.defineProperty(subType.prototype, 'constructor', {
    enumerable: false, // 主要设置不可遍历
    configurable: true,
    writable: true,
    value: subType,
  });
}

// test
// 父类通用属性和方法
function Person(name, age, friends) {
  this.name = name;
  this.age = age;
  this.friends = friends;
}

Person.prototype.running = function () {
  console.log('running~');
};

Person.prototype.eating = function () {
  console.log('eating~');
};

function Student(name, age, friends, sno, score) {
  Person.call(this, name, age, friends);
  // this.name = name;
  // this.age = age;
  // this.friends = friends;

  // 子类特有属性
  this.sno = sno;
  this.score = score;
}
// 原型继承
inheritPrototype(Student, Person);
// 子类特有方法
Student.prototype.studying = function () {
  console.log('studying~');
};

难点

1、万物皆对象。

  • 普通数据类型(字符串,数字),数组,Math,Date等顶层原型都指向对象原型,因为原型本身也是一个对象类型。 除了null、undefined。

2、函数都是new Function创建,自己生自己= =

毕业考试

  • 话不多说,上经典图。能看懂就毕业O(∩_∩)O哈哈~

image.png