继承与原型链

159 阅读2分钟

原型和原型对象的区别和对应关系

1.原型和原型对象的所属关系

(a)作为构造函数具有原型对象(原型对象中嵌有原型),且含有原型.
(b)作为构造函数创建出并不作为构造函数的实例对象,没有原型对象,只有原型且嵌有原型

2.原型和原型对象的访问写法

 (a)原型访问:对象名.__proto__,实际名称为[[prototype]]
 (b)原型对象访问:对象名.prototype
 

3.原型和原型对象在创建时形成的继承关系

代码:var 实例对象名 = new 构造函数名(参数)

 (1)由new创建一个空对象
 (2)将构造函数中的原型对象prototype引用且复制到实例对象中的原型[[prototype]]
 (3)调用构造函数中的执行语句,this指当前new创建的空对象
 (4)在内存中为实例对象创建空间,分配地址  

原型链

1.原型链的构成

 例1:
     <script>
        function add(){
           var n = 1;
        }
        var add1 = new add();   
     </script>
  //1.这里的原型链属于add1的原型(等价于add的原型对象)
  //add1.__proto__ == add.prototype
  //add1.__proto__.__proto__ == add.prototype.__proto__ == Object.prototype
  //add1.__proto__.__proto__.__proto__ == add.prototype.__proto__.__proto__ == Object.prototype.__proto__ == null   
  
  //2.这里的原型链属于add函数的原型
  //add.__proto__ == Function.prototype
  //add.__proto__.__proto__ == Function.prototype.__proto__ == Object.prototype
  //add.__proto__.__proto__.__proto__ == Object.prototype.__proto__ == null

2.原型链的访问机制(依次往下)

(1)先去检查对象上的属性.若有,则调用对象上的属性.
(2)若对象上的属性没有,则遍历原型链中去查找属性.若有,则调用原型链上的属性
(3)若原型链上没有这个属性,则返回undefined

3.查找原型链中是否含有属性

(1)一般情况,进行访问,则会遍历整个原型链导致性能变差
(2)使用Object.hasOwnProperty()方法,不会遍历原型链,且会返回truefalse来表达结果

4.生成原型链的方法

(1)使用语法结构创建的对象
    var 对象名 = /\d{9}/
    console.log(a.__proto__ == RegExp.prototype);//true  
(2)使用构造函数创建的对象
    function add(){var n = 1;}
    var add1 = new add();  
    console.log(add1.__proto__ == add.prototype);//true
(3)Object.create()创建的对象
    var a = {b:1};
    var b = Object.create(a);
    console.log(b.__proto__ == a);//true
(4)使用class关键字创建的对象

5.函数和类的关系

 class Dog{
     constructor(name,age){
         this.name = name;
         this.age = age;
     }
     eat(){
         console.log('eat');
     }
 }
 
 等于
 function Dog(name,age){
     this.name = name;
     this.age = age;
 }
 
 Dog.prototype.eat = function(){
     console.log('eat');
 }
 
 const dog = new Dog('包子',3);