【前端八股】1分26秒看懂js原型及原型链

前情提要

年初准备找实习的我急急忙忙在网上下载了一堆前端面试八股,开始了废食忘寝的预习......

打开不同的资料,发现都能碰到同样的问题:【谈谈你对 JS 原型和原型链的理解?】

看一眼回答:

不死心再找教程看看:

PS:没有说别的教程不好的意思,是我愚笨!!!

直到在哔哩哔哩大学看到了这个视频: 【js原型链、构造函数和类】

仅仅1分26秒的视频,详情请见评论区:

大半年过去了,再回顾一下,整理个文档。

一、构造函数

简单概括:构造函数是用 new 关键字 调用,并且首字母大写,本质上也是个函数。

举个栗子

假如你是Riot公司的一名程序员,领导让你使用js重新开发lol这款游戏。需要100多个创建英雄到系统内,如果一个一个写,要写到地老天荒。于是先写个构造函数:

ini 复制代码
function Hero(name, title, role) {
    this.name = name;
    this.title = title;
    this.role = role;
};

有了构造函数,创建英雄new一下就搞定了

ini 复制代码
const Jiakesi = new Hero('贾克斯', '武器大师', '战士');
const Yidashi = new Hero('易大师', '无极剑圣', '刺客');

总的来说

所谓构造函数,就是提供一个生成对象的模板,并描述对象的基本结构的函数。一个构造函数,可以生成多个对象,每个对象都有相同的结构。

JS中使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类(理解为模板,表示某一类实物的共同特征)。我们将通过这个构造函数创建的对象,称为是该类的实例。

优点
  • 减少代码重复‌:使用构造函数可以减少代码的重复,特别是在需要创建大量具有相同属性的对象时。
  • 初始化对象 ‌:构造函数的主要用途是初始化对象,通过this关键字为对象设置属性和方法。这种方式使得对象的创建和初始化更加简洁和直观‌2。
  • 语法简洁 ‌:构造函数提供了一种简洁的书写方式,使得对象的创建更加方便和直观。通过new关键字调用函数,可以自动创建一个新的对象,并初始化其属性‌。
  • 提高代码的可读性和可维护性‌:使用构造函数可以使代码更加模块化,提高代码的可读性和可维护性。
有点缺点
  • 缺点1:如果构造函数中有很多的方法那么就会开辟很多的空间,浪费内存资源。

    javascript 复制代码
    function Person(name,age){
        this.name = name,
        this.age = age,
        this.sayhi = function(){
            console.log('构造函数中的方法');
        }
    }
    
    var Person1 = new Person('小白',12)
    var Person2 = new Person('大白',22)
    Person1.sayhi()
    Person2.sayhi()
    console.log(Person1 === Person2, Person1.sayhi === Person2.sayhi); //false false
  • 缺点2: 如果在全局情况下声明函数,虽然解决了内存资源浪费的问题,但是又会出现全局变量污染的问题。

    javascript 复制代码
    function say(){
        console.log('构造函数中的方法');
    }
     function Person(name,age){
            this.name = name,
            this.age = age,
            this.sayhi = say
        }
        var Person1 = new Person('小白',12)
        var Person2 = new Person('大白',22)
        Person1.sayhi()
        Person2.sayhi()
        console.log(Person1 === Person2, Person1.sayhi === Person2.sayhi); //false true
  • 缺点3: 可以重新声明一个对象专门存放这些方法,但是新的问题时,如果有很多个构造函数,就要声明很多个这样的对象。

    javascript 复制代码
    var obj = {
        say: function () {
            console.log('函数中的say方法');
        },
        hi: function () {
            console.log('函数中的hi方法');
        }
    }
    function Person(name, age) {
        this.name = name,
            this.age = age,
            this.sayhi = obj.say
    }
    var Person1 = new Person('小白', 12)
    var Person2 = new Person('大白', 22)
    Person1.sayhi()
    Person2.sayhi()
    console.log(Person1 === Person2, Person1.sayhi === Person2.sayhi); //false true

为解决创建构造函数的弊端,可以直接使用【原型对象】。

二、 原型对象

给出概念

js规定每个函数都有一个原型属性 (__proto__),指向一个原型对象 (prototype)。

js继承机制的设计思想:原型对象 (prototype) 的所有属性和方法都能被实例对象共享。

  • 对象:new关键字创建的实例对象;
  • 原型:又称原型对象,通常写作:构造函数名.prototype;
  • prototype:构造函数的属性;
  • proto:对象的属性

举个栗子

ini 复制代码
// 这是一个构造函数
function Person(name, age) {
    this.name = name;
    this.age = age;
}

//在原型上添加属性和方法
Person.prototype.xp = 'all';
Person.prototype.sayHello = function () {
    console.log('Hello, I'm + this.name')
}

// 创建(实例)一个对象
let p1 = new Person('Lily',18)

这里的Person.prototype是对象Person的原型

它们的关系如图:

构造函数通过new关键字创建对象(P1对象);

对象(P1对象)通过__proto__指向它的原型(Person.prototype);

原型(Person.prototype)中有所有对象公用的属性和方法(如xp和sayHello);

原型只能通过构造函数(constructor)来创建对象;

构造函数也可以通过prototype属性指向原型;

原型可以看作对象的本体,通过构造函数这个模板工具来创建对象。所以

  • 每个对象都有原型;对象.__proto__ 是原型(Person.prototype)
  • 每个原型都有与之对应的构造函数; 构造函数.prototype 是原型(Person.prototype)

三、原型链

原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

javascript 复制代码
// 原型对象本身是一个普通对象,而普通对象的构造函数都是Object
Person.prototype.__proto__ == Object.prototype

// Object的原型对象也有__proto__属性指向null,null是原型链的顶端
Object.prototype.__proto__ == null

总结:一切对象都是继承自Object对象,Object 对象直接继承根源对象null

相关推荐
LeeZhao@3 小时前
【AIGC】大模型面试高频考点-多模态RAG
人工智能·面试·职场和发展·aigc·ai agent
软件测试曦曦3 小时前
16:00面试,16:08就出来了,问的问题有点变态。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
低调包含4 小时前
面试(十一)
面试·职场和发展
济南小草根7 小时前
参加面试被问到的面试题
java·面试
且听风吟7208 小时前
JS综合解决方案5——模块化和构建工具
javascript·面试
海绵波波1079 小时前
集群聊天服务器面试问题
运维·服务器·面试
就是有点傻10 小时前
C#中面试的常见问题004
面试·职场和发展·c#·wpf
码上有前11 小时前
【51-60期】深入解析Java面试问题:从高并发到性能调优的最佳实践
java·开发语言·面试