1 <!DOCTYPE html>
  2 <html>
  3 <head lang="en">
  4     <meta charset="UTF-8">
  5     <title></title>
  6
  7     <script type="application/javascript">
  8
  9         //基于伪装的继承
 10         /**
 11          * call方法:
 12          语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]])
 13          定义:调用一个对象的一个方法,以另一个对象替换当前对象。
 14          说明:
 15          call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
 16          如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
 17          */
 18         function Parent(){
 19             this.color = ["red","blue"];
 20             this.name = "Leon";
 21         }
 22
 23         function Child(){
 24             //在Child中的this明显应该是指向Child的对象
 25             //当调用Parent方法的时候,而且this有时指向了Child
 26             //此时就等于在这里完成this.color = ["red","blue"]
 27             //也就是等于在Child中有了this.color的属性,这样也就变相的完成了集成
 28
 29             Parent.call(this);
 30
 31             //这种调用方式,Parent的上下文是Parent对象,根本无法实现继承
 32             //Parent();
 33         }
 34
 35         var c1 = new Child();
 36         c1.color.push("green");
 37         console.info(c1.color); //["red", "blue", "green"]
 38         var c2 = new Child();
 39         console.info(c2.color); //["red", "blue"]
 40         console.info(c2.name); //Leon
 41
 42
 43         function Parent2(name){
 44             this.color = ["red","blue"];
 45             this.name = name;
 46         }
 47
 48         function Child2(name , age){
 49             //在Child中的this明显应该是指向Child的对象
 50             //当调用Parent方法的时候,而且this有时指向了Child
 51             //此时就等于在这里完成this.color = ["red","blue"]
 52             //也就是等于在Child中有了this.color的属性,这样也就变相的完成了集成
 53
 54             this.age = age;
 55             Parent2.call(this , name);
 56
 57             //这种调用方式,Parent的上下文是Parent对象,根本无法实现继承
 58             //Parent();
 59         }
 60
 61         var c3 = new Child2("Leon" , 12);
 62         c3.color.push("green");
 63         console.info(c3.color); //["red", "blue", "green"]
 64         console.info(c3.name + "  "  + c3.age); //Leon  12
 65         var c4 = new Child2("Ada" , 22);
 66         console.info(c4.color); //["red", "blue"]
 67         console.info(c4.name + "  " + c4.age); //Ada  22
 68
 69         //这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4);
 70         // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。
 71         function add(a,b){
 72             console.info(a+b);
 73         }
 74         function sub(a,b){
 75             console.info(a-b);
 76         }
 77
 78         add.call(sub,3,1); //4
 79
 80
 81
 82         //call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat
 83         function Animal(){
 84             this.name = "Animal";
 85             this.showName = function(){
 86                 console.info(this.name);
 87             }
 88         }
 89
 90         function Cat(){
 91             this.name = "Cat";
 92         }
 93
 94         var animal = new Animal();
 95         var cat = new Cat();
 96
 97         //通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
 98         //输入结果为"Cat"
 99         animal.showName.call(cat,","); //Cat
100         animal.showName.apply(cat,[]);//Cat
101
102
103
104
105         // Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.
106         function Animal2(name){
107             this.name = name;
108             this.showName = function(){
109                 console.info(this.name);
110             }
111         }
112
113         function Cat2(name){
114             Animal2.call(this, name);
115         }
116
117         var cat2 = new Cat2("Black Cat");
118         cat2.showName();//Black Cat
119
120
121
122         //
123         //实现多继承
124         // 很简单,使用两个 call 就实现多重继承了
125         //  当然,js的继承还有其他方法,例如使用原型链,这个不属于本文的范畴,只是在此说明call 的用法。
126         // 说了call ,当然还有 apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments
127         // 还有 callee,caller..
128         function Class10(){
129             this.showSub = function(a,b){
130                 console.info(a-b);
131             }
132         }
133
134         function Class11() {
135             this.showAdd = function(a,b){
136                 console.info(a+b);
137             }
138         }
139
140         function Class2(){
141             Class10.call(this);
142             Class11.call(this);
143         }
144
145         var c2 = new Class2();
146         c2.showSub(1,2);
147         c2.showAdd(1,2);
148
149     </script>
150
151 </head>
152 <body>
153
154 </body>
155 </html>

基于伪造继承问题:

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6
 7     <script type="application/javascript">
 8
 9        //基于伪造的继承存在问题:
10
11
12         function Parent2(name){
13             this.color = ["red","blue"];
14             this.name = name;
15         }
16
17        //由于使用伪造的方式,不会完成Child的原形指向Parent,所以say方法不存在,
18        //解决方法:将该say方法放入到Parent2中使用this来创建,
19        // 但是又有新问题:每个对象中又存在say方法,这样空间占用太大,所有也不会单独的方式实现
20        Parent2.prototype.say = function(){
21            console.info(this.name);
22        }
23
24
25         function Child2(name , age){
26             //在Child中的this明显应该是指向Child的对象
27             //当调用Parent方法的时候,而且this有时指向了Child
28             //此时就等于在这里完成this.color = ["red","blue"]
29             //也就是等于在Child中有了this.color的属性,这样也就变相的完成了集成
30
31             this.age = age;
32             /*
33              * 使用伪造的方式就可以吧自雷的构造函数参数传递到父类中
34              */
35             Parent2.call(this , name);
36
37             //这种调用方式,Parent的上下文是Parent对象,根本无法实现继承
38             //Parent();
39         }
40
41         var c3 = new Child2("Leon" , 12);
42         c3.color.push("green");
43         console.info(c3.color); //["red", "blue", "green"]
44         console.info(c3.name + "  "  + c3.age); //Leon  12
45        c3.say(); //异常: Uncaught TypeError: c3.say is not a function
46         var c4 = new Child2("Ada" , 22);
47         console.info(c4.color); //["red", "blue"]
48         console.info(c4.name + "  " + c4.age); //Ada  22
49
50
51     </script>
52
53 </head>
54 <body>
55
56 </body>
57 </html>

解决伪造继承的问题;

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6
 7     <script type="application/javascript">
 8
 9
10         /**
11          * 组合的实现方式是属性通过伪造的方法实现,方法通过原形连的方式实现
12          *
13          */
14
15         function Parent(name){
16             this.color = ["red","blue"];
17             this.name = name;
18         }
19
20        Parent.prototype.ps = function(){
21            console.info(this.name + "[ " + this.color + "]");
22        }
23
24
25         function Child(name , age){
26             Parent.call(this,name);
27             this.age = age;
28         }
29
30
31         Child.prototype = new Parent();
32         Child.prototype.say = function(){
33             console.info(this.name + "  " + this.age + "  " + this.color);
34         }
35
36         var c1 = new Child("Leon" , 22) ;
37         c1.color.push("green");
38         c1.say(); //Leon  22  red,blue,green
39         c1.ps(); //Leon[ red,blue,green]
40         var c2 = new Child("Ada" , 23) ;
41         c2.say(); //Ada  23  red,blue
42     </script>
43
44 </head>
45 <body>
46
47 </body>
48 </html>

转载于:https://www.cnblogs.com/a757956132/p/5454121.html

js 基于函数伪造的方式实现继承相关推荐

  1. js中函数的使用方式及回调函数

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. jS四种函数的调用方式

    6- js 函数的四种调用方式 2016年11月04日 13:41:54 阅读数:7559 函数的四种调用方式 函数有下列调用模式 函数调用模式 方法调用模式 构造器模式 上下文模式 函数调用 模式 ...

  3. [js] axios为什么可以使用对象和函数两种方式调用?是如何实现的?

    [js] axios为什么可以使用对象和函数两种方式调用?是如何实现的? axios 源码 初始化 看源码第一步,先看package.json.一般都会申明 main 主入口文件. // packag ...

  4. JS基于编码方式实现加密解密文本

    JS基于编码方式实现加密解密文本 严格来讲这是一种简单的编码方式:加密,将明文[注]转成编码.解密则是编码转码为明文本. [注:明文是指没有加密的文字(或者字符串),一般人都能看懂.] 下面源码用到 ...

  5. js 函数定义的方式

    js 函数定义的方式 一.总结 一句话总结: 最常见就下面三种 最常见:function func1([参数]){/*函数体*/} 将匿名函数赋值给变量:var func2=function([参数] ...

  6. 原生JS基于window.scrollTo()封装垂直滚动动画工具函数

    概要: 原生JS基于window.scrollTo()封装垂直滚动动画工具函数,可应用与锚点定位.回到顶部等操作. ####封装原因: 在vue项目中,遇到需要实现垂直滚动效果的需求,初步想到的方法有 ...

  7. 拿到JS异步函数返回值的几种方式

    在我们的编码过程中,为了满足业务需求,经常需要获取JS异步函数的返回值.今天就来汇总一下拿值的几种方式. 1,通过回调函数的方式来拿返回值,这个想必大家不会陌生 function getSomethi ...

  8. JS定义函数的两种方式:函数声明和函数表达式

    函数声明 关于函数声明的方式,它的一个重要的特性就是函数声明提升(function declaration hoisting),意思是在执行代码之前会先读取函数声明.这就意味着可以把函数声明放在调用它 ...

  9. async 函数——JS中的异步处理方式

    async 函数的语法 async function name([param[, param[, ... param]]]) { statements } name: 函数名称. param: 要传递 ...

最新文章

  1. 【CMAC小脑】CMAC逼近sin(t)函数的训练和测试
  2. 斯坦福cs161算法考试的cheat sheet!!!十分重要!!!
  3. iOS NSUserDefaults 简介 NSUserDefaults 存储自定义对象
  4. 深入理解XGBoost:分布式实现
  5. php代码金字塔几种,php输出金字塔的2种实现方法
  6. 小师妹学JVM之:java的字节码byte code简介
  7. [LeetCode][Java] Unique Paths II
  8. .NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(下)
  9. SqlServer 对 数据类型 text 的操作
  10. chartControl控件常用属性总结
  11. XShell免费版的安装配置教程以及使用教程(超级详细、保姆级)
  12. android apk参数错误,Android adb安装apk时出现报错Invalid APK file如何解决
  13. 训练网络时指定gpu显卡
  14. 宝塔linux 搭建rtmp+ffmpeg转流直播服务器
  15. C语言之如何判断闰年:
  16. 知识图谱文献综述(第二章 知识表示学习)
  17. NCT 127‘英雄回归’:最精英的一批练习生走着最难的一条路
  18. == 和 ===的区别
  19. 数学建模常用Matlab/Lingo/c代码总结系列——最小费用最大流问题
  20. sql server2005完全卸载与重装

热门文章

  1. php preg_match 只匹配第一个字符_PHP正则表达式核心技术完全详解 第3节
  2. android 程序必须有界面,Android开发之开机启动没有界面的应用程序
  3. it男java_java-学习8
  4. linux实现开机自启动脚本
  5. 大字段 CLOB/BOLB与String互转
  6. Mybatis数据库连接报错:对实体 “characterEncoding“ 的引用必须以 ‘;‘ 分隔符结尾
  7. Windows下给WSL子系统(Kali)换源,使用binwalk,outguess等工具
  8. java boolean 包_java Boolean包装类工作笔记
  9. 操作系统—死锁的检测和解除
  10. 牛客网 正则表达式匹配