js原型与原型链了解一下

411 阅读3分钟

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

最近这一两年一直沉浸于使用框架,各种轮子来开发项目。小到时间类型转化,大到界面UI,富文本组件等都能找到符合需求,容易上手的轮子来实现。使用现成的轮子可以极大的提高开发的效率,同时也可以减少bug的出现,毕竟成熟的轮子的用户量还是很大的,有大量的用户测试过使用起来还是很放心的。人总是会在安逸下逐渐变得懒惰的(当然主要指的是我自己),使用过多的轮子开发,就会造成一些基础知识点的遗忘,所以今天就回顾一下js比较基础的原型与原型链。当然也是为了某一天的提桶提前做准备。

构造函数

构造函数其实是能创建对象的函数,构造函数的首字母需要大写,并且构造函数必须使用new来调用,没有用new调用的函数则是普通函数

function Person(name, age) {
     this.name = name
     this.age = age
     this.setName = function() {
         console.log(this.name)
     }
}
let person1 = new Person('susu', 14)
let person2 = new Person('yu')

那么我们就来看一下new到底做了一些什么操作

  1. 创建了一个空对象
  2. this会指向这个空对象
  3. 把对象的内置属性 _proto_ 指向函数对象的prototype属性
  4. return this指向的对象

上面的代码中person1和person2都是Person的实例,这两个实例都有constructor属性,并且都指向Person,换句话说就是实例的构造函数属性指向其构造函数,constructor是对象的属性

因此,constructor也可以用来判断对象的类型(类似于instanceof)

person1(person2).constructor == Person
person1(person2).constructor == Object // person1和person2也是Object的实例,因为对象继承于Object

prototype

prototype是创建函数对象时被包含的基础属性,是函数独有的属性。翻译成中文就是原型,指向函数的原型对象, 只有函数对象才有prototype属性,prototype属性可以给已有的对象添加属性和方法。

那么prototype主要用来做什么呢?

prototype其实可以使对象的实例对象共享prototype属性的所有属性和方法,下面的代码正是证实了这一点。

function Person() {}

Person.prototype.name = 'lucy'
Person.prototype.age = 22
Person.prototype.sayName = function() {
    console.log(this.name);
}

let person1 = new Person()
person1.sayName() // 输出‘lucy’
let person2 = new Person()
person2.sayName() // 输出‘lucy’

person1.sayName == person2.sayName

原型对象

原型对象其实就是普通对象,上面提到了函数对象的prototype属性指向函数的原型对象

通常情况下,原型对象都有一个构造函数属性(即constructor),该属性指向prototype所在的函数

Person.prototype.constructor == Person

实例的构造函数属性指向构造函数

person1.constructor == Person

_proto_

_proto_是js创建对象时的内置属性, 是对象的属性,指向创建他的构造函数的原型对象

person1._proto_ == Person.prototype

那么_proto_主要用来做什么呢?

其实我们可以把_proto_看成是连接原型链的纽带。当我们访问一个对象的属性时,如果不存在该属性,那么_proto_就会去其所指向的对象(也就是上级对象)里找,如果上级对象也不存在这个属性,会继续往上级对象的_proto_属性所指向的那个对象里找,如果还没找到,则会一直往上找,直到原型链的终点null

原型链栗子

function Person() {}
let person1 = new Person()

person1._proto_ == Person.prototype

person1的_proto_等于person1构造函数的prototype
person1.constructor == Person

Person.prototype._proto_ == Object.prototype

Person.prototype是一个原型对象,其实也是一个普通对象,即Object.prototype

Object.prototype._proto_ == null

Object.prototype 对象的_proto_属性为nullnull是原型链的顶端

Person._proto_ == Function.prototype

函数对象的`_proto_`指向Function.prototype

Function.prototype._proto_ == Object.prototype

js一切皆对象

Object.prototype._proto_ == null

Object.prototype 对象的_proto_属性为nullnull是原型链的顶端

文章有不足的地方还请各位多多指教!