ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript的“继承”

2021-12-15 19:33:34  阅读:140  来源: 互联网

标签:function Bar 继承 JavaScript 对象 原型 prototype 构造函数


原型链:每个对象内部存在一个内部链接,它会引用其他对象(称为原型对象),如果对象上没有找到需要的属性或者方法引用,引擎会去它链接的原型对象上查找,如果找不到再去链接的对象自身的原型对象上查找,以此类推,直到查找到Object的prototype原型对象,这一系列对象的链接就称作原型链。

在构造函数、实例和原型对象之间的原型链可以具体表现为:每个构造函数都有一个原型对象、原型对象上有一个属性指回构造函数、实例上有一个内部指针指向原型对象。当原型对象是另一个类型的实例时,就会和另一个组实例、原型对象、构造函数之间相关联,从而形成这些对象之间的链接。代码表现为下:

function Bar(){
  console.log('Bar构造函数')
}
//new 关键字实际上是创建了一个新对象并原型对象关联。
let bar1 = new Bar();  // bar1 实例

Bar.prototype // 指向原型对象
Bar.prototype.constructor // 指向构造函数
bar1.__proto__ // 指向原型对象
console.log(bar1.__proto__ === Bar.prototype) //true


//扩展
//new方法的简单实现
let newMethod = function (Parent, ...rest) {
  // 1.以构造器的prototype属性为原型,创建新对象;
  let child = Object.create(Parent.prototype);
  // 2.将this和调用参数传给构造器执行
  let result = Parent.apply(child, rest);
  // 3.如果构造器没有手动返回对象,则返回第一步的对象
  return typeof result  === 'object' ? result : child;
};

继承的实现方式:

1、原型链继承

通过改变默认原型对象为另一对象的实例实现

function Parent(){
  console.log("父类")
}
function Child(){
  console.log("子类")
}
Child.prototype = new Parent();

2、盗用构造函数继承

在子类构造函数中调用父类构造函数,利用apply,call实现。

function Parent(){
  console.log("父类")
}
function Child(){
  Parent.call(this);
  console.log("子类")
}
let child = new Child();

3、组合继承
利用原型链继承原型上的属性与方法,再盗用构造函数继承实例属性。

function Parent(name){
  this.name = name;
  console.log("父类")
}
function Child(name, age){
  //继承属性
  Parent.call(this,name); 
  this.age = age;
  console.log("子类")
}
//继承方法
Child.prototype = new Parent();

4、原型式继承

通过一个临时构造函数实现原型链继承。

function object(o){
  function F(){};
  F.prototype = o;
  return new F();
}
//ES5增加了Object.create()方法以实现原型式继承
//ES6之后,新增setPrototypeOf、getPrototypeOf
Object.setPrototypeOf(Bar.prototype, Foo.prototype);

5、寄生式继承

创建一个实现继承的函数、以某种方式增强对象,然后返回这个对象。

function createAnother(origin){
  let clone = Object.create(origin)
  //以某种方式增强对象
  clone.sayHi = function(){
    console.log('hi');
  }
   //返回这个对象
  return clone;
}

6、寄生组合继承

使用寄生式继承来继承父类原型,然后将返回的新对象赋值给子类原型。

function extendPrototype(Child, Parent){
  //创建指向原型指向Parent的对象prototype
  let prototype = Object.create(Parent); 
   //修复丢失的构造函数
  prototype.constructor = Child; 
  Child.prototype = prototype;  
}

以上是javaScrpit中的几种继承方式,然而除了构造函数继承外,涉及[[prototype]]的继承实际上都是对象之间的委托关联。javaScrpit中的继承不是像传统类那样执行复制操作。

委托是不同于类的设计模式,对象并不是按照父类到子类的关系垂直组织的,而是通过任意方向的委托关联并排组织的。

let Foo = {
  setName: function(Name) { this.name = Name; },
  getName: function() { console.log( this.name ); }
};
  // 让Bar委托Foo
let Bar = Object.create( Foo );
// Bar是存在一个原型对象指向Foo的对象。
Bar.SetNameAndAge = function(Name,Age) { 
  this.setName( Name );
  this.age = Age;
};
Bar.getNameAndAge = function() { 
  this.getName();
  console.log( this.age ); 
};
// 让b1委托Bar
let b1 = Object.create( Bar );
b1.SetNameAndAge('tom',3)
// 让b2委托Bar
let b2 = Object.create( Bar );
b2.SetNameAndAge('jerry',4)

b1.getNameAndAge()
b2.getNameAndAge()

 

标签:function,Bar,继承,JavaScript,对象,原型,prototype,构造函数
来源: https://www.cnblogs.com/hugebook/p/15694581.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有