Javascript Prototype

构造函数

每个实例都有一个constructor属性,指向他的构造函数。
每一个原型对象都有一个默认的属性constructor。
每一个constructor都指向一个原型对象。

JS 原型(prototype)

Javascript对象可以从原型对象继承属性,这种原型式继承(prototypal inheritance)是Javascript的核心。原型中定义的函数只在JavaScript加载时被创建一次,创建的每个对象都可以调用原型中的方法。

  • 每个Javascript函数都有一个prototype属性(Function.bind()除外)
  • 每个对象有一个proto属性指向该对象constructor.prototype,但只有函数才有prototype属性

以上面Book类为例, 原型、构造函数和实例对象的关系如下图所示:

constructor-prototype-instance-relation

即:

1
2
3
4
var book1=new Book("Harry Potter","J.K.Rowling");
book1.__proto__===Book.prototype; // true
book1.constructor===Book //true
Book.prototype.constructor===Book // true

所有的函数对象都继承自Function.prototype,因此有:

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
Number.__proto__ === Function.prototype  // true
Number.constructor == Function //true

Boolean.__proto__ === Function.prototype // true
Boolean.constructor == Function //true

String.__proto__ === Function.prototype // true
String.constructor == Function //true

// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身
Object.__proto__ === Function.prototype // true
Object.constructor == Function // true

// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身
Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

Array.__proto__ === Function.prototype // true
Array.constructor == Function //true

RegExp.__proto__ === Function.prototype // true
RegExp.constructor == Function //true

Error.__proto__ === Function.prototype // true
Error.constructor == Function //true

Date.__proto__ === Function.prototype // true
Date.constructor == Function //true

而Math与JSON以对象形式存在,所以:

1
2
3
4
5
Math.__proto__ === Object.prototype  // true
Math.construrctor == Object // true

JSON.__proto__ === Object.prototype // true
JSON.construrctor == Object //true

再一个例子

1
2
3
4
5
6
7
8
function Person(){}
var person1 = new Person();
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype) //true
console.log(Object.prototype.__proto__) //null

Person.__proto__ == Function.prototype; //true
console.log(Function.prototype)// function(){} (空函数)

注意:

  • 大部分prototype都是object类型,但Function.prototype是function类型。
  • Object.prototype.proto=null 由于Object是所有类的父类,类似于根节点,所以其prototype的proto为null。
  • 当试图引用某对象的某属性时,首先会在该对象的内部查找是否有该属性,找不到,就会去对象的proto属性里找,接着又会在proto属性所指的对象的proto里查找,一直查到Object的Protot。

instanceof 运算符

左侧为待测的实例对象,右侧为构造函数(构造函数即类名,是类的共有标识)。instanceof会检查左侧对象是否继承自右侧构造函数的prototype对象。可以不是直接继承。

参考

https://www.jianshu.com/p/dee9f8b14771