JS 基础篇(五) 继承方法总结

news/2024/7/19 15:47:35 标签: prototype, js, class, object
class="baidu_pl">
class="article_content clearfix">
class="markdown_views prism-atom-one-dark">

原型链继承

  1. code
class="prism language-class="tags" href="/tags/JS.html" title=js>js"> class="token keyword">function class="token function">Parentclass="token punctuation">(class="token punctuation">) class="token punctuation">{
   class="token keyword">thisclass="token punctuation">.cars class="token operator">= class="token punctuation">[class="token string">'Lamborghini'class="token punctuation">,class="token string">'Maserati'class="token punctuation">,class="token string">'Bentley'class="token punctuation">]class="token punctuation">;
 class="token punctuation">}
 Parentclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">showCars class="token operator">= class="token keyword">function class="token punctuation">(class="token punctuation">) class="token punctuation">{
   class="token comment">// console.log(this.cars);
 class="token punctuation">}class="token punctuation">;
 class="token keyword">function class="token function">Childclass="token punctuation">(class="token punctuation">) class="token punctuation">{class="token punctuation">}
 Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototype class="token operator">= class="token keyword">new class="token class-name">Parentclass="token punctuation">(class="token punctuation">)class="token punctuation">;
 class="token comment">// let parent = new Parent()
 class="token comment">// parent.cars.push('QQ')
 class="token comment">// console.log(parent.cars);
 class="token keyword">var child1 class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token punctuation">)class="token punctuation">;
 child1class="token punctuation">.carsclass="token punctuation">.class="token function">pushclass="token punctuation">(class="token string">'QQ'class="token punctuation">)
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(child1class="token punctuation">.carsclass="token punctuation">)class="token punctuation">;
 class="token keyword">var child2 class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token punctuation">)class="token punctuation">;
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(child2class="token punctuation">.carsclass="token punctuation">)class="token punctuation">;
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(Childclass="token punctuation">.__proto__ class="token operator">== Objectclass="token punctuation">.__proto__class="token punctuation">)class="token punctuation">;
  1. 思路
    将子构造函数的原型指向父构造函数的一个实例
  2. 总结
    优点:可以通过 instanceof 和 isPrototypeOf 的检测
    缺点
    1.子构造函数实例化对象时 不能传参,
    2.子实例化对象共享父构造函数的属性(比如cars),一旦改变,其他都改变
    子实例化对象相互影响

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

  1. code
class="prism language-class="tags" href="/tags/JS.html" title=js>js"> class="token keyword">function class="token function">Parentclass="token punctuation">(nameclass="token punctuation">) class="token punctuation">{
   class="token keyword">thisclass="token punctuation">.cars class="token operator">= class="token punctuation">[class="token string">'Lamborghini'class="token punctuation">,class="token string">'Maserati'class="token punctuation">,class="token string">'Bentley'class="token punctuation">]class="token punctuation">;
   class="token keyword">thisclass="token punctuation">.name class="token operator">= name
 class="token punctuation">}
 Parentclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">showCars class="token operator">= class="token keyword">function class="token punctuation">(class="token punctuation">) class="token punctuation">{
   consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token keyword">thisclass="token punctuation">.nameclass="token punctuation">)class="token punctuation">;
 class="token punctuation">}class="token punctuation">;
 
 class="token keyword">function class="token function">Childclass="token punctuation">(class="token operator">...argsclass="token punctuation">)class="token punctuation">{
   Parentclass="token punctuation">.class="token function">callclass="token punctuation">(class="token keyword">thisclass="token punctuation">,argsclass="token punctuation">)   class="token comment">//子构造函数里 借用父构造函数
 class="token punctuation">}
 class="token keyword">let child1 class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token string">'one'class="token punctuation">)
 child1class="token punctuation">.class="token function">showCarsclass="token punctuation">(class="token punctuation">)
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(child1class="token punctuation">)class="token punctuation">;
 
 class="token keyword">let child2 class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token string">'two'class="token punctuation">)
 child2class="token punctuation">.class="token function">showCarsclass="token punctuation">(class="token punctuation">)
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(child2class="token punctuation">.nameclass="token punctuation">)class="token punctuation">;
  1. 思路:在子构造函数内部调用父构造函数
  2. 总结
    优点
    1.可以向子构造函数传递参数
    2.子实例化对象相互不影响
    缺点:方法在函数中定义,无法调用父构造函数的方法
    注意:父构造函数并没有与子构造函数 建立联系
    所以,子实例化对象的原型身上并没有 showCars 方法

组合继承

  1. code
class="prism language-class="tags" href="/tags/JS.html" title=js>js">class="token keyword">function class="token function">Parentclass="token punctuation">(nameclass="token punctuation">, ageclass="token punctuation">) class="token punctuation">{
  class="token keyword">thisclass="token punctuation">.name class="token operator">= nameclass="token punctuation">;
  class="token keyword">thisclass="token punctuation">.age class="token operator">= ageclass="token punctuation">;
  class="token keyword">thisclass="token punctuation">.uselessclass="token operator">=class="token string">'empty'
class="token punctuation">}
Parentclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">show class="token operator">= class="token keyword">function class="token punctuation">(class="token punctuation">) class="token punctuation">{
  class="token comment">//  console.log(this.name + this.age);
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token string">"Parent show"class="token punctuation">)class="token punctuation">;
class="token punctuation">}class="token punctuation">;
class="token comment">//  let parent = new Parent('parent','40')
class="token comment">//  for (const key in parent) {
class="token comment">//    console.log(key);
class="token comment">//  }
class="token keyword">function class="token function">Childclass="token punctuation">(class="token operator">...argsclass="token punctuation">) class="token punctuation">{
  Parentclass="token punctuation">.class="token function">applyclass="token punctuation">(class="token keyword">thisclass="token punctuation">, argsclass="token punctuation">)class="token punctuation">;  class="token comment">//借用构造函数  实现传参
class="token punctuation">}

Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototype class="token operator">= class="token keyword">new class="token class-name">Parentclass="token punctuation">(class="token punctuation">)class="token punctuation">;   class="token comment">//  原型链继承  实现调用父构造身上的方法
class="token comment">// 这里要将子构造函数的构造器指回 Child
class="token comment">// 否则,子构造函数上没有constructor方法,根据原型链向上找到父构造函数的constructor,
class="token comment">// 最终指向了父构造函数
class="token comment">// 子构造函数原型方法还可能被覆盖掉
Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.constructor class="token operator">= Childclass="token punctuation">;
class="token comment">//  console.log(Child.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototype.constructor);
Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">show class="token operator">= class="token keyword">function class="token punctuation">(class="token punctuation">) class="token punctuation">{
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token string">"child show"class="token punctuation">)class="token punctuation">;
class="token punctuation">}class="token punctuation">;
consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token keyword">new class="token class-name">Parentclass="token punctuation">(class="token punctuation">)class="token punctuation">)class="token punctuation">;
class="token keyword">let child class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token string">"kk"class="token punctuation">, class="token string">"18"class="token punctuation">)class="token punctuation">;
class="token comment">//  child.show()
class="token keyword">let child2 class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token string">"lele"class="token punctuation">, class="token string">"13"class="token punctuation">)class="token punctuation">;
class="token comment">//  child2.show()
consoleclass="token punctuation">.class="token function">logclass="token punctuation">(child2class="token punctuation">)class="token punctuation">;
class="token keyword">for class="token punctuation">(class="token keyword">const key class="token keyword">in child2class="token punctuation">) class="token punctuation">{
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(keyclass="token punctuation">)class="token punctuation">;
class="token punctuation">}
  1. 思路:
    结合原型链继承实现调用父构造函数的方法
    利用借用构造函数实现传参定义属性
  2. 总结
    组合继承:结合了原型链继承和构造函数继承
    **优点:**同时可以传递参数,共享父构造函数方法,而且有自己的方法
    缺点:
    1.两次调用了父构造函数,浪费内存
    2.constructor 可以被 in 遍历出来

原型式继承

  1. code
class="prism language-class="tags" href="/tags/JS.html" title=js>js">class="token keyword">function class="token function">Parentclass="token punctuation">(class="token punctuation">)class="token punctuation">{
   class="token keyword">thisclass="token punctuation">.cars class="token operator">= class="token punctuation">[class="token string">'Lamborghini'class="token punctuation">,class="token string">'Maserati'class="token punctuation">,class="token string">'Bentley'class="token punctuation">]
 class="token punctuation">}
 Parentclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">show class="token operator">= class="token keyword">functionclass="token punctuation">(class="token punctuation">)class="token punctuation">{
   consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token keyword">thisclass="token punctuation">.carsclass="token punctuation">)class="token punctuation">;
 class="token punctuation">}
 
 class="token keyword">let parent class="token operator">= class="token keyword">new class="token class-name">Parentclass="token punctuation">(class="token punctuation">)
 class="token keyword">function class="token function">objectclass="token punctuation">(objclass="token punctuation">)class="token punctuation">{
   class="token keyword">function class="token function">Fnclass="token punctuation">(class="token punctuation">)class="token punctuation">{class="token punctuation">}
   Fnclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototype class="token operator">= obj
   class="token keyword">return class="token keyword">new class="token class-name">Fnclass="token punctuation">(class="token punctuation">)
 class="token punctuation">}

 class="token keyword">let obj class="token operator">= class="token function">objectclass="token punctuation">(parentclass="token punctuation">)
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(objclass="token punctuation">)class="token punctuation">;
 class="token comment">// 原型式继承
 class="token comment">// 不需要父构造函数,根据父构造函数的实例化对象,模拟一个对象

2.总结
根据父构造函数的实例化对象,模拟一个对象
优点
不需要知道父构造函数
缺点
只是赋值了一个对象出来,无法传参

寄生继承

  1. code
class="prism language-class="tags" href="/tags/JS.html" title=js>js">  class="token keyword">let parentclass="token operator">=class="token punctuation">{
    nameclass="token punctuation">:class="token string">'parent'class="token punctuation">,
    ageclass="token punctuation">:class="token string">'18'
  class="token punctuation">}
  class="token keyword">function class="token function">objectclass="token punctuation">(objclass="token punctuation">)class="token punctuation">{  class="token comment">//这里手动实现了Object.create()
    class="token keyword">function class="token function">Fnclass="token punctuation">(class="token punctuation">)class="token punctuation">{class="token punctuation">}
    Fnclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototype class="token operator">= obj
    class="token keyword">return class="token keyword">new class="token class-name">Fnclass="token punctuation">(class="token punctuation">)
  class="token punctuation">}
  class="token keyword">function class="token function">createclass="token punctuation">(objclass="token punctuation">)class="token punctuation">{   class="token comment">//
    class="token keyword">let clone class="token operator">= class="token function">objectclass="token punctuation">(objclass="token punctuation">)
    cloneclass="token punctuation">.class="token function-variable function">haveclass="token operator">=class="token keyword">functionclass="token punctuation">(class="token punctuation">)class="token punctuation">{
      consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token string">'clone have car'class="token punctuation">)class="token punctuation">;
    class="token punctuation">}
    class="token keyword">return clone
  class="token punctuation">}
  class="token keyword">let child class="token operator">= class="token function">createclass="token punctuation">(parentclass="token punctuation">)
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(childclass="token punctuation">.nameclass="token punctuation">)class="token punctuation">;
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(childclass="token punctuation">.ageclass="token punctuation">)class="token punctuation">;
  childclass="token punctuation">.class="token function">haveclass="token punctuation">(class="token punctuation">)
  1. 总结
    寄生继承
    优点:根据对象克隆一个具有相同属性和方法的对象,而且可以具有自己的方法
    缺点:无法被复用,无法传参

寄生组合继承

code

class="prism language-class="tags" href="/tags/JS.html" title=js>js">class="token keyword">function class="token function">extendclass="token punctuation">(supclass="token punctuation">,subclass="token punctuation">)class="token punctuation">{
  subclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototype class="token operator">= Objectclass="token punctuation">.class="token function">createclass="token punctuation">(supclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">)  class="token comment">// 重置子构造函数的原型
  Objectclass="token punctuation">.class="token function">definePropertyclass="token punctuation">(subclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">,class="token string">'constructor'class="token punctuation">,class="token punctuation">{   class="token comment">//修正原型链
    valueclass="token punctuation">:subclass="token punctuation">,
    enumerableclass="token punctuation">:class="token boolean">false
  class="token punctuation">}class="token punctuation">)
class="token punctuation">}
class="token keyword">function class="token function">Parentclass="token punctuation">(nameclass="token punctuation">,ageclass="token punctuation">)class="token punctuation">{
  class="token keyword">thisclass="token punctuation">.name class="token operator">= name
  class="token keyword">thisclass="token punctuation">.age class="token operator">= age
class="token punctuation">}
Parentclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">show class="token operator">= class="token keyword">functionclass="token punctuation">(class="token punctuation">)class="token punctuation">{
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token keyword">thisclass="token punctuation">.nameclass="token operator">+class="token string">':'class="token operator">+class="token keyword">thisclass="token punctuation">.ageclass="token punctuation">)class="token punctuation">;
class="token punctuation">}
class="token keyword">let parent class="token operator">= class="token keyword">new class="token class-name">Parentclass="token punctuation">(class="token string">'parent'class="token punctuation">,class="token number">18class="token punctuation">)
consoleclass="token punctuation">.class="token function">dirclass="token punctuation">(parentclass="token punctuation">)class="token punctuation">;

class="token keyword">function class="token function">Childclass="token punctuation">(class="token operator">...argsclass="token punctuation">)class="token punctuation">{
  Parentclass="token punctuation">.class="token function">applyclass="token punctuation">(class="token keyword">thisclass="token punctuation">,argsclass="token punctuation">)   class="token comment">//借用构造函数,并实现传参
class="token punctuation">}
class="token function">extendclass="token punctuation">(Parentclass="token punctuation">,Childclass="token punctuation">)  class="token comment">//实现继承
Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">show class="token operator">= class="token keyword">functionclass="token punctuation">(class="token punctuation">)class="token punctuation">{   class="token comment">// 子构造函数 覆盖父构造函数的show方法
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token string">'Child show'class="token punctuation">)class="token punctuation">;
class="token punctuation">}
Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.class="token function-variable function">getName class="token operator">= class="token keyword">functionclass="token punctuation">(class="token punctuation">)class="token punctuation">{  class="token comment">// 子构造函数 可以有自己的方法
  consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token keyword">thisclass="token punctuation">.nameclass="token punctuation">)class="token punctuation">;
class="token punctuation">}
class="token keyword">let child class="token operator">= class="token keyword">new class="token class-name">Childclass="token punctuation">(class="token string">'kk'class="token punctuation">,class="token number">18class="token punctuation">)
consoleclass="token punctuation">.class="token function">dirclass="token punctuation">(childclass="token punctuation">)class="token punctuation">;
childclass="token punctuation">.class="token function">getNameclass="token punctuation">(class="token punctuation">)

consoleclass="token punctuation">.class="token function">logclass="token punctuation">(Childclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">.__proto__ class="token operator">== Parentclass="token punctuation">.class="tags" href="/tags/PROTOTYPE.html" title=prototype>prototypeclass="token punctuation">)class="token punctuation">;
consoleclass="token punctuation">.class="token function">logclass="token punctuation">(Childclass="token punctuation">. __proto__ class="token operator">== Objectclass="token punctuation">.__proto__class="token punctuation">)class="token punctuation">;

  1. 总结
    class之前是最完备的继承方式

class_205">class类继承

class="prism language-class="tags" href="/tags/JS.html" title=js>js">class="token keyword">class class="token class-name">Userclass="token punctuation">{
   class="token function">constructorclass="token punctuation">(nameclass="token punctuation">)class="token punctuation">{
     class="token keyword">thisclass="token punctuation">.name class="token operator">= name
     class="token keyword">thisclass="token punctuation">.cars class="token operator">= class="token punctuation">[class="token string">'Lamborghini'class="token punctuation">,class="token string">'Maserati'class="token punctuation">,class="token string">'Bentley'class="token punctuation">]
   class="token punctuation">}
   class="token function">getCarsclass="token punctuation">(class="token punctuation">)class="token punctuation">{
     consoleclass="token punctuation">.class="token function">logclass="token punctuation">(class="token keyword">thisclass="token punctuation">.carsclass="token punctuation">)class="token punctuation">;
     
   class="token punctuation">}
 class="token punctuation">}
 class="token keyword">class class="token class-name">Admin class="token keyword">extends class="token class-name">Userclass="token punctuation">{
   class="token function">constructorclass="token punctuation">(nameclass="token punctuation">,ageclass="token punctuation">)class="token punctuation">{
     class="token keyword">superclass="token punctuation">(nameclass="token punctuation">)
     class="token keyword">thisclass="token punctuation">.age class="token operator">=age
   class="token punctuation">}
 class="token punctuation">}
 class="token keyword">let admin class="token operator">= class="token keyword">new class="token class-name">Adminclass="token punctuation">(class="token string">'admin'class="token punctuation">,class="token number">18class="token punctuation">)
 adminclass="token punctuation">.class="token function">getCarsclass="token punctuation">(class="token punctuation">)
 consoleclass="token punctuation">.class="token function">logclass="token punctuation">(adminclass="token punctuation">.ageclass="token punctuation">)class="token punctuation">;
    class="token comment">/*
      总结:完美
    */

http://www.niftyadmin.cn/n/1852548.html

相关文章

关于this的全面解析(call,apply,new)

我们在写代码的时候,时常会被this弄的傻傻分不清楚,看源码的时候也经常被call啊apply啊弄的头皮发麻。this到底是什么?本文主要根据书上和实际应用做了一些归纳。一般情况下this有4种绑定规则: 1、默认绑定 - this指向全局变量 举…

RedHat Linux 9.0的安装(详细图解安装过程)

RedHat Linux版本:" b, t) b) b# }, t# z- fC& S$ x0 }) GRedHat Linux是目前世界上使用最多的Linux操作系统。因为它具备最好的图形界面,无论是安装、配置还是使用都十分方便,而且运行稳定,因此不论是新手还是老玩家都对它有很高的…

JS 基础篇(七) 函数柯理化

函数柯理化 定义 在计算机科学中&#xff0c;柯里化&#xff08;Currying&#xff09;是把接受多个参数的函数变换成 接受一个单一参数(最初函数的第一个参数)的函数&#xff0c; 并且返回接受余下的参数且返回结果的新函数的技术个人理解&#xff1a; sum(1,2,3) <> …

Ansible 拷贝文件或目录

写法如下&#xff1a; [rootlocalhost ~]$ ansible 192.168.119.134 -m copy -a "src/etc/passwd dest/tmp/passwd ownerroot grouproot mode0644" # 拷贝本机文件到远程客户端 [rootlocalhost ~]$ ansible 192.168.119.134 -m copy -a "src/etc/ansible des…

解决Windows Vista 英文版中文软件乱码

解决方法如下: 1, 开始->Control Panel->Regional and Language Options, Formats 标签里的 Current format 选择 Chinese (PRC); 2, Location 标签里的 Current location 选择 China; 3, Administractive 标签里单击 Change system locale 按钮, Current system locale …

JS 基础篇(一) instanceof、constructor

instanceof 定义&#xff1a;instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 语法&#xff1a;object instanceof constructor 参数&#xff1a; object 某个实例对象constructor 构造函数code function Car(make, model, year) …

java1.8新特性(三 关于 ::的用法)

java1.8 推出了一种::的语法 用法 身边 基本没人用1.8的新API 目前 我也是只处于学习 运用 阶段 有点 知其然不知其所以然 通过后面的学习&#xff0c;及时查漏补缺 一个类中 有 静态方法 ,非静态方法,构造方法 :: 操作静态方法package lambda;/*** author 作者:cb* version 创…

spring junit单元测试

项目是有很多个功能块组成的&#xff0c;我们开发的时候&#xff0c;当我们开发出来一个功能&#xff0c;想要测试这个功能是否正确&#xff0c;不可能等到前端和后端全部写好了再进行测试&#xff0c;这样太浪费时间&#xff0c;有没有什么方法能直接测试后台的功能写的是否正…