构造函数

构造函数是什么,简单理解我们创建一个类的方法,这个类有通性。比如人、动物、歌星这都是个类,有一些共同特性

function Star() {}
let p1 = new Star()

function Animal() {}
let animal = new Animal()

以上这两个例子都是类,构造函数想要用类创建出一个对象,必须要使用new

当我们创建明星,一个小明,一个小红,他俩都会唱歌,我们一般会如下创造

function Star(name, age) {
  this.name = name
  this.age = age
  this.sing = function () {
    console.log('我会唱歌')
  }
}

let xiaoming = new Star('小明', 12)
let xiaohong = new Star(' 小红', 18)

xiaoming.sing()
xiaohong.sing()

这样创造出来的两个人,想要唱歌就要调用sing()这个方法

发现问题没有,我们用Star创造的人,想唱歌都需要创建个sing()。是不是很浪费内存,这是 Star都会的功能,所以我们应该单独拿出来创建一次sing() 这个方法,所有人使用同一个函数来实现唱歌的功能,这才是最重要的
于是乎,就有了原型对象这个东西

原型对象

prototype 这个东西,其实创建一个构造函数,他就会有

JavaScript 规定:::每一个构造函数都有一个 prototype 属性::,他就是一个对象,这个对象的所有属性和方法都会被构造函数创建的所有对象拥有

我们再创建一个会唱歌的小蓝、小粉的时候,就优化了一下

function Star(name, age) {
  this.name = name
  this.age = age

}
Star.prototype.sing = function () {
  console.log('我们都会唱歌')
}

let xiaolan = new Star('小蓝', 80)
xiaolan.sing()

let xiaofen = new Star('小粉', 70)
xiaofen.sing()

只要是构造函数 Star 创建出来的对象,Star 的原型对象上绑定了唱歌的方法,那么所有人都可以共用这个方法,官方说:构造函数通过原型分配的函数是所有对象共享的

为什么这样呢?因为对象的原型

对象的原型

所有创建出来的对象都有 __proto__这个东西,他指向的就是构造函数的 prototype 原型对象,简言就是哪个构造函数创建了它,它就有个属性指向构造函数的原型对象,这样就可以使用构造函数的原型对象上绑定的所有方法和属性

function Star(name, age) {
  this.name = name
  this.age = age

}
Star.prototype.sing = function () {
  console.log('我们都会唱歌')
}

let xiaolan = new Star('小蓝', 80)
xiaolan.sing()

console.log(xiaolan.__proto__ === Star.prototype) // true

语言文字毕竟不如代码让大家看的清楚,这样就都明白了吧?

原型链

上述内容知道了,原型链就容易理解了,每个对象都有个 __proto__连接着构造函数的原型对象,我们使用方法的时候就会沿着__proto__去寻找。

例如:小蓝会唱歌,它通过 __proto__找到了Star这个构造函数的原型上有sing()方法,那它就可以调用,如果找不到,就找 Star 的原型对象的__proto__连接的地方,大家打印一下就是 Object.prototype,这样一层层的连接,就是原型链

原型链顶端连接的是 null

JavaScript 成员查找机制

1. 当方位一个对象的属性(方法)时,首先查找这个对象自身有没有该属性或者方法
2. 如果没有就查找它的原型(也就是__proto__指向的 prototype 原型对象)
3. 如果还没有就查找原型对象的原型(Object 的原型对象)
4. 依此类推,一直找到 Object 为止(null 是顶端)

constructor

这个就是指向构造函数

例如:xiaolan.constructor === Star

它是用来记录哪个构造函数创建的对象

两个总结的图

构造函数、原型、原型对象的关系

原型链


码路芽子
81 声望12 粉丝

简单的随心的