【前端八股】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

相关推荐
一小路一1 小时前
Go Web 开发基础:从入门到实战
服务器·前端·后端·面试·golang
纯粹要努力1 小时前
前端跨域问题及解决方案
前端·javascript·面试
uhakadotcom6 小时前
Next.js中生成sitemap的简单方法
前端·面试·架构
菠菠萝宝9 小时前
【Java八股文】08-计算机网络面试篇
java·计算机网络·http·面试·https·udp·tcp
无名之逆11 小时前
探索 Hyperlane:高性能 Rust Web 框架的崛起
java·开发语言·后端·python·算法·面试·rust
小钊(求职中)20 小时前
Java开发实习面试笔试题(含答案)
java·开发语言·spring boot·spring·面试·tomcat·maven
小小码农(找工作版)20 小时前
JavaScript 前端面试 4(作用域链、this)
前端·javascript·面试
阿芯爱编程21 小时前
前端面试题
前端·面试
uhakadotcom1 天前
约束求解领域的最新研究进展
人工智能·面试·架构
超爱吃士力架1 天前
MySQL 三层 B+ 树能存多少数据?
java·后端·面试