javascript 中的原型 ,原型链 ,继承

在js 中讲到 面向对象,就离不开原型  原型链  继承   等等概念;那么这些具体是什么,我们一起来深入理解。

function Dog(name){
   this.name= name ;
   this.barking = '汪汪汪';
}
var dog1 = new Dog('大狗');
var dog2 = new Dog ('二狗');

console.log(dog1);//{name:'大狗',barking:'汪汪汪'}
console.log(dog2); //{name:'二狗',barking:'汪汪汪'}
dog1.barking='汪汪';

console.log(dog1);//{name:'大狗',barking:'汪汪'}
console.log(dog2); //{name:'二狗',barking:'汪汪汪'}

从上面的代码 我们先声明了一个Dog 的 构造函数, 对Dog 使用new 关键字生成 对应的实例对象,从上面修改其中一个实例对象的属性,另一个不受影响。其实,每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费
javascript 的设计者 希望可以共享需要的方法和属性 ,此时 ,现在去掉实例中的 Barking 属性, 添加 prototype .

function Dog(name){
   this.name= name ;
}
Dog.prototype = { Barking : '汪汪汪,汪汪' }
 console.log(dog1.Barking) //  '汪汪汪,汪汪' 
 console.log(dog2.Barking) // '汪汪汪,汪汪'

 现在, Barking属性放到原型对象中, 只需要修改原型中的Barking ,  两个实例都能共享发生变化。
2. 原型链 :讲到原型 ,离不开原型链 , 讲到原型链离不开 _proto_  ;  

原型链是在Object.create() 或 DOG.prototype 创建原型对象时,生成的  _proto_ 指针来实现的 。
 如上例  实例对象dog1 的   _proto_ 指针, 指向了构造函数的原型对象Dog.prototype,原型对象上的_proto_ 指Object.prototype  ;
以上例 说明 当访问dog1上的Barking 属性 , 会先在dog1 上自有属性上找, 如果没有找到会通过_proto_指针 在 Dog.prototype ,找到了return 对应的值, 没有找到会继续沿着_proto_ 在 ,Object.prototype  ,终点为null 。

以上可以描述为 xxx.__proto__.__proto__.__proto__  ,通过_proto_ 指针 形成一个访问属性 或者方法的链 即为原型链;

总结一下原型链作用:对象属性的访问修改和删除。

  1. 访问。优先在对象本身查找,没有则顺着原型链向上查找
  2. 修改。只能修改跟删除自身属性,不会影响到原型链上的其他对象。

为了更好理解 原型可以参考下图


3.继承 

es5 以及更早的版本是通过 上方原型的方式进行继承, 组合继承 :

function Father (name){
  this.name= name;
}
 Father.prototype.say=function (){
   console.log('my name is ' + this.name);
}
function Child  (name){
    Father.call(this,name);  //  继承 构造函数Father的属性
}
Child.prototype = new Father() ;  Child 原型中的_proto_指针会指向 Father.prototype, 继承 构造函数Father 的原型;
var children1 = new Child('Tom'); 
children1.say(); // my name is Tom  

最后children1  访问say方法 , 先在自身找, 再通过 _proto_  在Child.prototype 找, 再通过 Child.prototype的_proto_在Father  的原型上找到say 方法 调用。

es6 中采用  class, extends 关键字实现继承, 使用起来非常方便,

class Parent {
   constructor(name){
      this.name=name;
         }
  getName(){
     console.log(this.name)
     }
 };
class Child extends Parent {
   constructor(name){
     super(name);
    }
};

var children1 = new  Child('Tom');
children1.getName(); // Tom
发布了16 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42317878/article/details/104610299