JavaScript深入之原型

每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。

function Person(){
    
    
    Person.prototype.name = "Pinocchio";
    Person.prototype.age = 14;
    Person.prototype.getName = function(){
    
    console.log(this.name);}
}
var person1 = new Person();
var person2 = new Person();
alert(person1.getName == person2.getName);   //true

优点:方法不会被重新创建 。 缺点:所有属性和方法都共享,无法初始化参数。比如原型中有一个引用类型,那么一个实例属性的改变会导致另一个实例属性也发生改变。

6.2.4.1 理解原型对象

创建一个新函数时,就会以特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。

默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针

注意:在找原型对象时,构造函数用的是prototype,对象实例用的是__proto__

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

在这里插入图片描述

如果实例的原型里也没有找到。由于实例的原型也是对象,因此原型对象也有自己的原型对象。

在这里插入图片描述

当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以:

person.constructor === Person.prototype.constructor
  • Object.getPrototypeOf() 可以方便得取得一个对象的原型。
alert(Object.getPrototypeOf(person1) == Person.prototype);  //true

在实例中添加一个原型中有的属性或将其设为null,会屏蔽原型对象中保存的同名属性,且不会修改原型里的属性。除非用delete删除实例中的属性才可以继续访问原型中的属性。

  • person1.hasOwnProperty('name') 如果实例中有该属性,则返回true,不会考虑原型中是否有。

  • "name" in person1 in操作符可以单独使用也可在for-in中使用。in会在通过对象能访问到给定属性时返回true,无论在实例还是原型里。

  • Object.keys(obj) 会返回一个包含所有可枚举属性的字符串数组,不包含原型。

  • Object.getOwnPropertyNames() 会返回所有实例属性,不管是否可枚举的字符串数组。

猜你喜欢

转载自blog.csdn.net/Pinoochio/article/details/113706682