原型链

原型对象

原型对象:构造函数的prototype属性:随着实例化的次数增加,不同的对象他们拥有的say方法指向不同的内存,能相同,造成了内存的浪费,为了解决内存,将这个方法放在某个对象(原型对象)中.

结论1:给构造函数的prototype属性(对象)添加一个方法,这个方法就可以被构造函数的实例所共享
推论1:构造函数的prototype属性(对象)上面的属性、方法都可以被构造函数的实例所共享
推论2:Student.prototype.constructor===s1.constructor
结论2:构造函数的实例有一个proto指向的是构造函数的prototype属性(原型对象) s1.proto===Student.prototype

(1). 原型对象是构造函数的prototype属性
(2). 构造函数的实例的proto属性指向原型对象
(3). 原型对象有一个constructor属性指向构造函数本身

原型链

对象的属性的读取与设置

查找一个对象上的是否存在某个属性的过程

(1). 查找当前对象(s1)的内存中是否定义了该属性,找到就停止查找
(2). 去当前对象的proto属性(原型对象)中去查找是否定义了该属性,找到就停止查找
(3). 如果2中没找到,就去原型对象的原型对象中去查找是否定义了该属性
(4). s1.__proto__.__proto__
……
(N). 找到某个对象(是没有原型对象的:没有proto属性),如果这个对象中还没有,确定了无法获取该属性

基本概念

JavaScript 的对象组成,一个对象就有它的原型对象(__proto__),原型对象也有它的原型对象,一直到原型链的顶端,这样构成了一个具有链条形状的结构,称之为原型链

  • __proto__该属性可以被修改,但是无法被删除

对象字面量的原型链

对象字面量的原型链

构造函数创建对象的原型链

构造函数创建对象的原型链

数组对象的原型链

数组对象的原型链

一般来说,无论是对象字面量,还是构造函数创建的对象、内置对象,基本包装了类型的对象,2次原型查找(.proto)就可以找到

函数的原型链

1
2
3
function f(){}
f();//f当成了普通函数来调用
new f();//f当成了构造函数来调用

一些结论:

  • 几乎所有函数都有prototype属性(Function.prototype这个函数上没有)
  • 所有对象中都有proto属性(Object.prototype该属性的值null)

—> 几乎所有函数都有prototype/__proto__属性

  • 函数都是Function的实例(函数是通过Function创建出来的对象)
    • ——> 自定义函数、Function、Array、RegExp、String、Boolean、Number、Object
  • 几乎所有函数都是继承自:Function.prototype(除了Function.prototype)
    • ——> 函数.__proto__ === Function.prototype
    • ——> Object.__proto__ === Function.prototype
    • ——> Function.__proto__ === Function.prototype
    • Function.prototype.__proto__ === Object.prototype
    • String.prototype.__proto__ === Object.prototype
    • Array.prototype.__proto__ === Object.prototype
    • Boolean.prototype.__proto__ === Object.prototype
    • Number.prototype.__proto__ === Object.prototype
    • RegExp.prototype.__proto__ === Object.prototype

练习

1
2
3
4
5
6
7
8
function fn(){}
1、console.log(fn.constructor===Function);//true //查找fn的内存——>查找fn.__proto__(Function.prototype)——>Function
2、console.log(fn.__proto__===_______);//true //Function.prototype
3、console.log(Object.__proto__===______);//true //Function.prototype
4、console.log(Function.prototype===______);//true //Function.__proto__——>fn.__proto__——>Object.__proto__
5、console.log(Object.constructor); //Function
6、console.log(fn.prototype.constructor); //fn
7、console.log(Function.prototype.__proto__.constructor); //Object

原型链完整图

原型链完整图

感谢您的支持!