Skip to content
^finished

原型

作用:通过构造函数的 pritotype ,可以存放一些公共的方法和属性,可以节省一定的内存空间。

写一个构造函数,名字要传递进来。

js
function Fn(name){
    this.name = name
    this.sex = ''
    this.age = 18
}
function Fn(name){
    this.name = name
    this.sex = ''
    this.age = 18
}

通过这个构造函数实例化两个对象,xmxh ,他们的年龄和性别一样,名字不一样。

js
let xm = new Fn('xiaoming')
let xh = new Fn('xiaohong')
let xm = new Fn('xiaoming')
let xh = new Fn('xiaohong')

Fn() 是构造函数,我们 new 了构造函数之后,就会给我们创建实例对象,这里创建了两个实例对象,系统开辟了两块空间分别存储这两个对象的信息。 但是我们发现,它们中一些属性值是完全一样的,可以把他们相同的属性和方法拿出来,每个实例对象对他们进行共用就可以了。

有什么办法可以实现共用?这就用到 prototype 属性了

prototype 是函数的属性,这个属性的值是一个对象。 所以 Fn() 这个函数就有 prototype 这个属性,而且我们可以在这个属性(值是对象)里面添加一些属性和方法。

js
function Fn(name){
    this.name = name
}
Fn.prototype.sex = ''
Fn.prototype.age = 18
function Fn(name){
    this.name = name
}
Fn.prototype.sex = ''
Fn.prototype.age = 18

怎样使用实例出来的对象?这就要用到 _proto_ 属性了。 _proto_ 是对象的属性,而 prototype 是函数的属性。实例化出来的对象的 _proto_ 属性指向的就是构造函数的 prototype 属性(完全相等)。

js
let xm = new Fn('xiaoming')
let xh = new Fn('xiaohong')
let xm = new Fn('xiaoming')
let xh = new Fn('xiaohong')

原型链

  • 作用:通过原型链,可以做一些方法和属性的继承

我们强调过对象都会有一个 _proto_ 属性,并且,构造函数的 prototype 也是一个对象。 那么构造函数的 prototype 也有一个 _proto_ 属性,这个 _proto_ 指向谁取决于我们有没有让它专门让它指向另外一个构造函数的 prototype 。如果没有指定的话,它会一直往外面找,一直找到 Object ,指向 Object.prototype

  1. 比如我要在实例对象 person 里面找一个属性 name ,首先它会看自己有没有这个属性
js
Object.prototype.skill = '踢足球'
function Fn(name){
    this.name = name
}
Fn.prototype.skill = '唱歌'
let person = new Fn()
person.skill = '游泳'
console.log(person.skill) // 游泳,是它本身的属性
Object.prototype.skill = '踢足球'
function Fn(name){
    this.name = name
}
Fn.prototype.skill = '唱歌'
let person = new Fn()
person.skill = '游泳'
console.log(person.skill) // 游泳,是它本身的属性
  1. 没有的话就会顺着原型链找,先是通过它自身的 _proto_ 属性,然后找到构造函数的 prototype 里面设置的公共属性和方法 mo'gu
js
Object.prototype.skill = '踢足球'
function Fn(name){
    this.name = name
}
Fn.prototype.skill = '唱歌'
let person = new Fn()
// person.skill = '游泳' // 注释掉
console.log(person.skill) // 唱歌,来自构造函数的属性
Object.prototype.skill = '踢足球'
function Fn(name){
    this.name = name
}
Fn.prototype.skill = '唱歌'
let person = new Fn()
// person.skill = '游泳' // 注释掉
console.log(person.skill) // 唱歌,来自构造函数的属性
  1. 如果这里还没有的话,那就继续通过 prototype_proto_ 属性,一直找到 objectprototype
js
Object.prototype.skill = '踢足球'
function Fn(name){
    this.name = name
}
// Fn.prototype.skill = '唱歌' // 也注释掉
let person = new Fn()
// person.skill = '游泳' // 注释掉
console.log(person.skill) // 踢足球,来自Object.prototype
Object.prototype.skill = '踢足球'
function Fn(name){
    this.name = name
}
// Fn.prototype.skill = '唱歌' // 也注释掉
let person = new Fn()
// person.skill = '游泳' // 注释掉
console.log(person.skill) // 踢足球,来自Object.prototype
  1. 如果这里还没有,那就是 undefined
js
// Object.prototype.skill = '踢足球' // 也注释掉
function Fn(name){
    this.name = name
}
// Fn.prototype.skill = '唱歌' // 也注释掉
let person = new Fn()
// person.skill = '游泳' // 注释掉
console.log(person.skill) // undefined,Object也没有了,那就真没有了
// Object.prototype.skill = '踢足球' // 也注释掉
function Fn(name){
    this.name = name
}
// Fn.prototype.skill = '唱歌' // 也注释掉
let person = new Fn()
// person.skill = '游泳' // 注释掉
console.log(person.skill) // undefined,Object也没有了,那就真没有了