likes
comments
collection
share

深入了解JS原型

作者站长头像
站长
· 阅读数 54

前言

在JS里,原型非常重要,他是JS的核心特征之一,主要用于继承对象的属性和方法。今天让我们一起深入了解一下原型。

原型

1.原型是函数自带的一个属性(prototype),它定义了构造函数创建的实例对象公共祖先。而通过构造函数创建的对象可以继承该函数原型上的属性。

2.实例对象隐式具有构造函数原型上的属性,且只是可读属性

举个例子:

Car.prototype.name = 'NININJA H2'
Car.prototype.lang = 3000
Car.prototype.height = 170


function Car(color,owner) {
    // this.name = 'NININJA H2'
    // this.lang = 3000
    // this.height = 170
    this.color = color
    this.owner = owner
}

let car1 = new Car('black','Kakarotto')
let car2 = new Car('white','Sun GoKu')
console.log(car1,car2);
console.log(car1.name,car1.lang,car1.height)

这段代码的执行结果如下:

深入了解JS原型

从输出结果可以看到,实例对象可以继承到原型属性上的方法和属性,且实例对象隐式具有构造函数原型上的属性。不强调输出构造函数原型上的属性我们是无法看到的。

但是话又说回来了,为什么说实例对象隐式具有构造函数原型上的属性是可读属性呢?

让我们再看一个例子:

Person.prototype.like = 'FPS'
function Person(){
    this.name = 'Ro9nin'
        this.age = 18
}
let P = new Person()

console.log(P.like);

输出结果如下:

深入了解JS原型

那我们对这段代码稍作修改:

Person.prototype.like = 'FPS'
function Person(){
    this.name = 'Ro9nin'
        this.age = 18
}
let P = new Person()
console.log(P.like);

P.like = 'Jerk off'

console.log(P);
console.log(P.like);

delete P.like;
console.log(P.like);

输出结果如下:

深入了解JS原型

由此可见,虽然在对象P增加了属性like后输出的P.like改变了,但是这输出的只是添加在对象P上的属性like的值,在删除P.like后输出的依旧是Person.prototype.like = 'FPS'的值。因此可知实例对象只能够访问原型上的属性,不能够进行修改,即实例对象隐式具有构造函数原型上的属性是可读属性

原型链

V8在查找对象中的属性时,如果没找到,就会顺着对象那个的隐式原型往上查找,还找不到,再顺着隐式原型的隐式原型往上找,直到找到null为止,在这过程中但凡有一个步骤就能找到,就会返回值。这个链状的查找过程称为原型链。 举例如下:

   Person.prototype.lastName = 'Kakarotto';
    function Grand(){
        this.name = "Ro9nin";
    }
    Father.prototype = new Grand()
    function Father(){
        this.age = 21;
    }
    Son.prototype = new Father();
    function Son(){
        this.like = "FPS";
    }
    let son = new Son();
    console.log(son.like);
    console.log(son.age);

这段代码的输出结果大家应该也知道,输出的是FPS和21.那这两个属性是怎么被访问到的呢?

在探究这个问题之前我们先要知道一句话:对象上的__proto__属性,它等于构造函数的prototype,在这句话的基础上我们再去探究上个问题。

prototype是构造函数的显式属性, 深入了解JS原型 是对象的隐式属性。 当访问son.like和son.age时,V8引擎的查找顺序是这样的:

   //  __proto__: Son.prototype == new Father(){
   //          __proto__: Father.prototype == new Grand(){
   //              __proto__: Grand.prototype == new Person(){
   //                  __proto__: Person.prototype == new Object{
   //                      __proto__: Object.prototype {
   //                          __proto__: null
   //                  }
   //              }
   //          }
   //      }

即:

深入了解JS原型

这样一步步执行寻找下去,最终形成一个完整的原型链

附上一张图标帮助大家理解原型链:

深入了解JS原型

总结

转载自:https://juejin.cn/post/7377468457388900390
评论
请登录