Skip to content
On this page

原型(prototype)、原型链(__proto__

函数

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

对象

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

原型(prototype)

  • 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(null除外)

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

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

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

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

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

js
// 要点一:自由扩展属性
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;

// 要点二:__proto__
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);

// 要点三:函数有 prototype
console.log(fn.prototype)

// 要点四:引用类型的 __proto__ 属性值指向它的构造函数的 prototype 属性值
console.log(obj.__proto__ === Object.prototype)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

原型链

  • 它是一种基于 __proto__向上查找的机制。当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性或者方法
  • 找到了,则结束查找,使用自己私有的即可
  • 没有找到,则基于** proto** 找所属类 prototype , 如果找到就用这个公有的,如果没找到,基于原型上的、_ __proto__继续向上查找,一直找到 0bject.prototype 的原型为止,如果在没有,操作的属性或者方法不存在
  • 每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性
javascript
// 原型 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__);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

特殊 Function Object

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

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

那么如何判断这个属性是不是对象本身的属性呢?使用hasOwnProperty,常用的地方是遍历一个对象的时候。

js
var item
for (item in f) {
    // 高级浏览器已经在 for in 中屏蔽了来自原型的属性,但是这里建议大家还是加上这个判断,保证程序的健壮性
    if (f.hasOwnProperty(item)) {
        console.log(item)
    }
}
1
2
3
4
5
6
7

原型链中的this

所有从原型或更高级原型中得到、执行的方法,其中的this在执行时,就指向了当前这个触发事件执行的对象。因此printNamealertName中的this都是f

沪ICP备20006251号-1