JavaScript基础-原型(prototype)、原型链(__proto__)

2,588 阅读2分钟

这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

函数

普通函数、类(所有的类:内置类、自己创建的类)

对象

  • 普通对象、数组、正则、Math、arguments...
  • 实例是对象类型的(除了基本类型的字面量创建的值)
  • prototype 的值也是对象类型的
  • 函数也是对象类型的

原型(prototype)

  • 所有的函数数据类型都天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存

  • 在浏览器给 prototype 开辟的堆内存中有一个天生自带的属性: constructor, 这个属性存储的值是当前函数本身

  • 每一个对象都有一个 __proto__ 的属性,这个属性指向当前实例所属类的 prototype (如果不能确定它是谁的实例,都是 object 的实例)

  • 每一个类都把供实例调取的公共属性方法存储到自己的原型上(原型 prototype 的作用就是存储一些公共的属性和方法,供它的实例调取和使用)。

    JS 在创建对象的时候,都有一个 __proto__的内置属性,用于指向创建它的构造函数的原型对象。

原型链

image.png

  • 它是一种基于 __proto__向上查找的机制。当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性或者方法
  • 找到了,则结束查找,使用自己私有的即可
  • 没有找到,则基于** proto** 找所属类 prototype ,如果找到就用这个公有的,如果没找到,基于原型上的_ __proto__继续向上查找, 一直找到 0bject.prototype 的原型为止,如果在没有,操作的属性或者方法不存在
  • 每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性
// 原型 prototype 原型链 __proto__
// 每一个函数都有prototype属性
// 每一个对象都有__proto__属性
function Aniam() {
  var n = 100;
  this.a = "值";
  this.type = "哺乳类";
  this.AA = function () {
    console.log(`AA[私]`);
  };
  this.BB = function () {
    console.log(`BB[私]`);
  };
}
Fn.prototype.AA = function () {
  console.log(`AA[公]`);
};

var f1 = new Fn();
var f2 = new Fn();

console.log(f1.n);

Aniam.prototype.type = "哺乳";
Aniam.prototype.b = "原型";
// 先会查找自身的属性、向上查找则查找父类
console.log(Aniam.prototype);
let animal = new Aniam();
// delete animal.type
console.log(animal.type);
console.log(animal.__proto__ === Aniam.prototype);
console.log(animal.__proto__.__proto__ === Object.prototype);
console.log(Aniam.prototype.constructor === Aniam);
console.log(Object.__proto__.__proto__);

特殊 Function Object

// 特殊Function Object(可以充当对象、也可以充当函数)
console.log((Function.__proto__ = Function.prototype));

console.log("====================================");
// hasOwnProperty 智慧看是否存在当前实例上
console.log(animal.hasOwnProperty("a"));
// in 关键字 会判断这个属性是否属于原型 或者实例上的属性
console.log("b" in animal);
console.log("====================================");