【JS】原型继承

   1. 对象原型:
                对象原型为JS中对象的一个特殊的隐藏属性[[Prototype]],值为一个对象的引用或者null,引用所指向的对象为原型
 
            2. 原型继承:
                当读取一个对象的属性时,若没有,会自动从原型链中寻找。
     
一、原型链继承   
  // Supper函数
    function Supper(){
        this.supProp = 'supper prop'
    }
    // Supper函数原型上添加一个方法
    Supper.prototype.showSupper = function(){
        console.log(this.supProp);
    }

    // Sub函数
    function Sub(){
        this.subProp = 'sub Prop'
    }
 
    Sub.prototype = new Supper() // 将Sub函数的原型设置为一个Supper实例对象
    Sub.prototype.constructor = Sub // 在Sub原型中添加一个constructor属性,执行Sub函数自身
 
    // Sub原型上添加方法
    Sub.prototype.showSub = function(){
        console.log(this.subProp);
    }

    // 创建一个Sub实例
    const s = new Sub()
    console.log(s)
    s.showSub()
    s.showSupper()

pp

二、结合构造函数

function Person(name,age){
    this.name = name;
    this.age = age
}
Person.prototype.setName = function(name){
    this.name = name;
};

function Student(name,age,price){
    Person.call(this,name,age);//相当于this.Person(name,age)
    this.price = price;
}

Student.prototype = new Person();//为了看到父类型方法
Student.prototype.constructor = Student;//修正constructor属性

Student.prototype.setPrice = function(price){
    this.price = price;
};

var s = new Student('Tom',24,1500);
s.setName('Bob');
s.setPrice(100);
console.log(s.name,s.age,s.price);

pp

 

            3. 设置原型[[Prototype]]的方法:
                1. 使用__proto__,获取或设置对象原型。
                2. 使用Object.setPrototypeOf 或 Object.getPrototypeOf

 

                * __proto__ 是 [[Prototype]] 的因历史原因而留下来的 getter/setter,现代编程语言建议我们应该使用函数 Object.getPrototypeOf/Object.setPrototypeOf 来取代 __proto__ 去 get/set 原型
           
           4.  **原型只用于读取属性**
            写入/删除操作不用使用原型,直接加在对象身上即可。
            但访问器属性,赋值操作时由setter函数执行。若将对象身上写入一个属性,该属性为原型中访问器属性,则会调用原型中的setter和getter。

 

            5. this问题:
                **调用 obj.method(),无论在哪里找到方法:在一个对象还是在原型中。在一个方法调用中,this 始终是点符号 . 前面的对象。**
    
let animal = {
  eat() {
    this .full =  true ;
  }
};

let rabbit = {
  __proto__: animal
};

rabbit.eat();

    属性查找和执行是两回事儿。

    首先在原型中找到 rabbit.eat 方法,然后在 this=rabbit 的情况下执行。

           
            6. for..in循环会迭代继承的属性
            但几乎所有其他键/值获取方法都忽略继承的属性
             Object.keys()只会返回自己的key
              内建方法obj.hasOwnProperty(key),若obj自身有该属性则返回true,没有返回false
   7. 性能
    在现代引擎中,从性能的角度来看,我们是从对象还是从原型链获取属性都是没区别的。它们(引擎)会记住在哪里找到的该属性,并在下一次请求中重用它。一旦有内容更改,它们就会自动更新内部缓存,因此,该优化是安全的。
posted @ 2022-10-27 17:06  Ahoge的笔记本  阅读(115)  评论(0编辑  收藏  举报