likes
comments
collection
share

探讨JavaScript原型和原型链

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

原型和原型链

js没有类和对象的概念,但是有原型和原型链的概念,这JavaScript中的原型是指每个对象在创建的时候都会关联到另一个对象,这个对象就是该对象的原型,而原型链是指当访问一个对象的属性或方法的时候,如果该对象本身没有这个属性或方法,JavaScript就会沿着原型链向上查找,直到找到对应的属性和方法位置。

  • 原型链的作用在于实现了对象之间的继承关系
  • 原型的作用
    • 当我们通过引用对象的属性key来获取value的时候,他会触发get的操作

    • 这个操作会首先检查该对象是否有对应的属性,如果有就使用它

    • 如果对象中没有该属性,那么会访问对象prototpe内置属性指向的对象上的属性

如下是前端圈火热的JavaScript继承图,可以更好的看出来原型和原型链以及继承的关系

探讨JavaScript原型和原型链

-现在对上图进行解释,前置知识:

  • 每创建一个函数,就会同时创建它的prototype对象,所有的函数都有一个prototype的属性,这是函数对应的原型对象
  • 所有的原型对象都有constructor属性,它是用来指向当前的函数对象
    // 非常重要的属性: constructor, 指向Person函数对象
    function Person() {

    }

    // 1.对constructor在prototype上的验证
    var PersonPrototype = Person.prototype
    
    console.log(PersonPrototype)//Object  内含constructor
    console.log(PersonPrototype.constructor)//function Person
    console.log(PersonPrototype.constructor === Person)//true
    console.log(".............");
    console.log(Person.name)//Person
    console.log(PersonPrototype.constructor.name)//Person
  • JavaScript原型链,当一个对象上获取属性,如果在当前对象没有获取到就回去它的原型上面获取
// 2.原型链
    var obj = {
      name: "why",
      age: 18
    }

    // 查找顺序
    // 1.obj上面查找
    // 2.obj.__proto__上面查找
    // 3.obj.__proto__.__proto__ -> null 上面查找(undefined)
    // console.log(obj.message)


    // 3.对现有代码进行改造
    obj.__proto__ = {
      // message: "Hello aaa"
    }

    obj.__proto__.__proto__ = {
      message: "Hello bbbb"
    }

    obj.__proto__.__proto__.__proto__ = {
      message: "Hello ccc"
    }

    console.log(obj.message)
  • Object是一个内置的构造函数,用于创建对象,他是原型链的尽头,是所有类的父类
const person = {
    name: 'John',
    age: 30,
    greet: function() {
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    }
};
console.log(person.constructor === Object); // 输出: true

  • Function是一个内置的构造函数,用与创建函数对象,他是所有函数的类,因为JavaScript函数实际上都是Function类型的实例
function add(a, b) {
    return a + b;
}
console.log(add.constructor === Function); // 输出: true
  • 内置对象还有Array 、 Date 这些都是浏览器引擎给我们的,JavaScript内置的构造函数
  • prototype和_proto_之间的区别,其中prototype用于对象的原型链,_proto_用于实例的原型链,当你使用new关键词的时候,这就是实例化操作。当你用new创建一个对象的时候,JavaScript会自动为这个对象添加_proto_属性,并且这个对象指向函数的原型
 function Get(name){
        this.name = name
      }
      Get.prototype.sayhello = function(){
        console.log("hello")
      }

      const set = new Get("111")
      console.log(Get.prototype === set.__proto__)//true
  • 如下是其他版本图,原理和指向都是一样的。选择自己最喜欢的去学习即可 探讨JavaScript原型和原型链

好,现在我们学完了前置知识,我们来解析这张js的经典继承图,所有的函数和函数原型之间的关系都是相互的如下图视

探讨JavaScript原型和原型链

有几个重点,就是new出来的实例化函数,他是有_proto_属性的,并且这个per1.proto 指向person的原型对象的,这些全部的_Proto_最终都指向Object.prototype,因为Object是他们尽头,Object.prototype的_proto_指向null

探讨JavaScript原型和原型链

构造函数实现继承

因为JavaScript中没有类和对象的概念,JavaScript的设计者使用构造函数来实现继承机制