javascript 原型,有何特点,原型链是如何形成的?实现继承的几种方法,优缺点

原型链是如何形成的?

每个子类的实例对象都包含一个内部属性 _proto_ 属性,该属性包含一个指针,指向父类的prototype,即原型对象。若父类的原型对象的 _proto_ 属性再指向上层函数,即爷爷类的prototype,层层往上,就成了原型链。

JS 中每一个函数都存在原型对象属性 prototype,并且只有函数才有原型对象 prototype 属性
所有函数的默认原型都是Object 的实例

实现继承的几种方法,优缺点?

一、原型链继承法

子类的 prototype 属性指向父类实例

代码示例
 function Parent(){
   this.name = ['小黑','小白'];
 }

 Parent.prototype.getName = function(){
   console.log(this.name);
 }

 function Child(){

 }

 Child.prototype = new Parent(); //关键代码
缺点
  1. 父类引用类型的属性,会被所有实例共享,例如:
var myChild = new Child();
var herChild = new Child();
myChild.name.push('小黄');
console.log(myChild.name); //  ['小黑','小白','小黄'];
console.log(herChild.name); //  ['小黑','小白','小黄'];
  1. 创建子类实例时,不能像父类传参

二、借用构造函数继承法(经典继承)

在子类构造函数内通过call、apply,执行父类构造函数

代码示例
function Parent(){
  this.name = ["小黑","小白"];
}
function Child(){
  Parent.call(this);
}

var myChild = new Child();
var herChild - new Child();

myChild.name.push("小黄");

console.log(myChild.name); //  ["小黑","小白","小黄"]
console.log(myChild.name); //   ["小黑","小白"]
优点
  1. 避免引用类型的属性被所有实例共享
  2. 可以在子类实例化的时候,向父类传递参数,例如:
function Parent(name){
  this.name =name;
}
function Child(name){
  Parent.call(this,name);
}

var myChild = new Child('小黑');
var herChild = new Child('小白');

console.log(myChild.name); // 小黑
console.log(herChild.name); //小白

三、组合继承法

运用原型链继承和经典继承(借用构造函数继承法)
优点:融合原型链继承和借用构造函数继承的优点,是javascript中最常用的继承方式

代码示例
function Parent (name){
  this.name = name;
}

Parent.prototype.getName = function(){
  console.log(name)
}

function Child(){
  Parent.call(this,name);
  this.age = 20;
}

Child.prototype = new Parent();
Child.prototype.constructor = Child;//构造函数指向自身

你可能感兴趣的:(javascript 原型,有何特点,原型链是如何形成的?实现继承的几种方法,优缺点)