• 【原型与原型链】初识原型与原型链~


    原型与原型链是js的难理解的点之一,但是只要认真去理解,也会有所收获💜💜💜

    在介绍原型与原型链之前,我们先搞懂下面问题

    1. __proto__和constructor属性是对象所独有的;
    2. prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
    • 属性作用:
    1. __proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,然后返回undefined,再往上找就相当于在null上取值,会报错。通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
    2. prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.proto === Foo.prototype。
    3. constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function。

    1.原型

    • proto:隐式原型
    • prototype:显式原型
    • 对象都有隐式原型__proto__。
    • 函数有显示原型prototype。
    • 对象的__proto__指向其构造函数的prototype。
    • 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
    • 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
    • 所有引用类型的__proto__属性指向它构造函数的prototype

    下面先理解三个概念:

    1. proto

    每一个对象都有一个__proto__属性,他指向该对象的原型

    function Person(){}
    var person1 = new Person()
    console.log(person1.__proto__ === Person.prototype) // true
    
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    1. prototype

    每一个函数都有一个 prototype 属性,该属性指向函数的原型对象

    function Person(){}
    Person.prototype.name = "protoName"
    var person1 = new Person()
    console.log(person1.name) // protoName
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    解释:

    • person1本身没有name这个属性,所以它会去构造函数Person找,而Person函数本身也没有name属性,所以person1就会去Person.prototype上面找,也就是去Person的原型上面找

    在这里插入图片描述

    1. constructor

    每个原型都有一个constructor属性,指向该关联的构造函数。
    从constructor属性来讲,只有prototype对象才有这个属性,而其它对象的constructor属性都是通过__proto__对象从prototype继承而来

    function Person(){}
    var person1 = new Person()
    console.log(Person.prototype.constructor === Person) // true
    console.log(Person.prototype.constructor === person1.constructor) // true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    解释:

    • person1本身没有constructor属性,所以会沿着原型链想上查找,去它的构造函数Person上面查找,而构造函数的原型上面就有constructor属性

    在这里插入图片描述
    函数在创建时,JS会为该函数创建一个对应的prototype对象,而这个prototype对象的constructor属性又指向该函数,即Foo.prototype.constructor === Foo

    • 原型的优点
    • 原型对象上的所有属性和方法,都能被对应的构造函数创建的实例对象共享*(这就是 JavaScript继承机制的基本设计),也就是说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

    • 每一个构造函数都有一个prototype(原型)属性,这个属性就是使用构造函数创建出来的实例对象的原型对象。

    2.原型链

    • 原型链用于基于现有对象构建新类型的对象。它类似于基于类的语言中的继承。

    • 对象实例上的原型可通过Object.getPrototypeOf(object)或proto属性获得,而构造函数上的原型可通过Object.prototype 获得。

    原型链特点

    • 读取对象的某个属性时,JavaScript引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。
    • 如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding

    就近原则

    function Person(name,age){
    	this.name = name;
    	this.age = age;
    }
    Person.prototype.address = function(){
    	console.log("地址");
    }
    var  xiaoming= new Person("小明");
    xiaoming.address();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 解释:
    1. 构造函数Person通过prototype指向Person的原型对象prototype

    2. Person原型对象prototype通过自身具有的construtor属性指回构造函数Star

    3. Person创建了对象实例xiaoming,xiaoming通过自身具有的__proto__属性指向其原型对象

    • 注意点

    一级级向上,在原型链寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链

    以后有更深更好懂的解释,我会慢慢补充💜💜

  • 相关阅读:
    Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解
    【微信小程序从入门到精通(项目实战)】——微电影小程序
    git_回退到上一次commit与pull
    三级分类的数据表设计和构造API数据
    c语言malloc不初始化,为什么没有占用系统空闲内存
    VScode安装plantUML和graphviz的安装MAC
    pytorch基础学习个人笔记(3)
    【系统稳定性 - 调优】3.4 常见Binder相关异常调优总结
    poi多sheet,模板导出数据
    linux elf relationship between data structures involved in symbol resolution
  • 原文地址:https://blog.csdn.net/m0_62159662/article/details/126006743