cdq 的 Blog cdq 的 Blog

向死而生

目录
JavaScript 的原型个人理解
/  

JavaScript 的原型个人理解

  • 原型对象的理解
    我们创建的每一个函数都有一个 prototype 属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含一些特殊的属性和方法,方法是我们可以自己定义的,这个函数创建的每一个实例的 __proto__属性都指向该对象,它是所有实例化对象的原型。image.png如图所示,这就是Person 和 Person.prototype 所指对象的关系。

  • constructor
    当函数创建时,prototype 属性指向一个原型对象,这个对象默认会有一个 constructor 属性,这个属性是一个指针,指向 prototype 所在的函数对象,拿 Person 对象来说,Person.prototype.constructor 就指向 Person。更新后的关系图如下:image.png

  • 实例化对象的__proto__属性
    在我们创建一个实例对象后,这个实例对象里会包含一个指针,指向构造函数的原型对象,在 ECMA-262 第五版中管这个指针叫做 [[Prototype]] 。所有对象都有 [[Prototype]] 属性,指向他们的原型对象,
    根据前面的 Person 我们来实例化一个对象。

    let ddd = new Person()
    console.log(ddd.__proto__ === Person.prototype) // true
    

    上述代码的结果是true,我们可以看出,这个连接是存在于实例对象和构造函数的原型对象之间的,而不是存在实例对象和构造函数之间的。

    image.png

    更新后的关系图如上图所示。

  • isPrototypeOf()

    虽然我们无法在脚本里访问[[prototype]] 属性,但是我们可以通过 isPrototypeOf() 来确定两个对象之间是否存在这种关系。

    isPrototypeOf() 方法用于判断一个对象是否在另外一个对象的原型链上。

    console.log(Person.prototype.isPrototypeOf(student)); // true
    
  • Object.getPrototypeOf()

    在 ECMAScript 5 中新增了一个方法叫 Object.getPrototypeOf() ,可以返回[[prototype]]的值,如下:

    console.log(Object.getprototypeOf(student) === Person.prototype); // true
    
  • 原型属性

    每当代码读取到对象的属性时,会先在对象本身搜索这个属性,如果找到该属性就返回值,如果没找到,就会去该对象搜索对应的原型对象,以此类推。

    而这样的搜索顺序,如果我们在该实例中初始化一个属性,和该实例原型对象中的同名,那么在该实例中的属性将会替换原型对象中的属性。

  • 属性判断

    既然属性有可能是实例本身的,也有可能是原型对象的,那么有些时候我们就需要判断一下,在属性确认存在的时候,我们可以用hasOwnProperty()来判断是否是实例本身的属性,还是存在于原型对象中。这个方法只有属性存在于实例对象中时才会返回 true。

    let student = new Person()
    Person.prototype.name = 'laker'
    console.log(student.name);// laker
    console.log(student.hasOwnProperty("name"))// false
    
    student.name = 'xiaomin'
    
    console.log(student.name);// xiaomin
    console.log(student.hasOwnProperty("name"))// true
    

标题:JavaScript 的原型个人理解
作者:cdq
地址:http://cdqyyds.club/articles/2021/10/26/1635241068211.html