js 基于函数伪造的方式实现继承

  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>

时间: 2024-10-07 14:21:08

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

JS中函数的地方方式

JS中函数是特殊的对象,可以拥有自己的属性和方法,属性被定义为局部变量,这样可以有效地防止变量的污染,方法被定义为闭包(定义在函数内部的函数).JS中函数的实参和形参个数都可以不固定,通过arguments(实参对象)函数属性来调用,在函数内部arguments.length表示函数实参的个数,而arguments.callee.length表示函数的形参的个数.prototype称为原型属性, 1.通过函数直接量表达式定义(适合于只要使用一次的场景,在JS中使用最多的是回调函数): funct

08 js系统函数、js函数调用方式

在js 中函数分为:用户自定义函数.系统函数(查阅文档) 常用函数的介绍eval <html> <head> </head> <body> <script language="javascript"> var str="window.alert('OK')"; //需求是把str当做一个脚本来执行 eval(str);//计算 JavaScript 字符串,并把它作为脚本代码来执行. </script

JS的三种使用方式/CSS的三种使用方式/JS中的DOM事件模型/JS中匿名函数的书写及调用/媒体查询@media的三种使用方式

一.JS的三种使用方式 1.html标签中内嵌JS(不提倡使用.)                <button onclick="javascript:alert('你真点啊.')" > 有本事点我呀!!!!</button>                                2.HTML页面中直接使用JS:                <script type="text/javascript">        

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

函数声明 关于函数声明的方式,它的一个重要的特性就是函数声明提升(function declaration hoisting),意思是在执行代码之前会先读取函数声明.这就意味着可以把函数声明放在调用它的语句后面,如下所示: 1 sayHi(); //在调用语句的后面声明函数(function declaration hoisting) 2 function sayHi () { 3 console.log("Hello World"); 4 } 函数表达式 有多种表达方式,下面是最常见

js中定义函数的常用方式

1:函数声明 因为在js中有函数提升特性,所以函数声明可以写在作用域的任意地方. 2:函数表达式,又叫函数字面量 原文地址:http://blog.51cto.com/11871779/2119688

js 对象深复制,创建对象和继承

js 对象深复制,创建对象和继承.主要参考高级编程第三版,总结网上部分资料和自己的代码测试心得.每走一小步,就做一个小结. 1.对象/数组深复制 一般的=号传递的都是对象/数组的引用,如在控制台输入 var a=[1,2,3], b=a; b[0]=0; a[0] 此时显示的结果为0,也就是说a和b指向的是同一个数组,只是名字不一样罢了. 单层深复制: 1.js的slice函数: 返回一个新的数组,包含下标从 start 到 end (不包括该元素,此参数可选)的元素. 控制台输入: var a

对JS中函数的理解

函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能) var fn=function(a){return a+100;} fn=function(a){return a+200;} alert(fn(100)); //300 要访问函数的引用(指针)而不是执行函数时,必须去掉圆括号,加上圆括号表示访问函数执行后的结果 函数体内部的语句在执行时,一旦

原型、函数伪装(apply,call)、继承

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>原型与继承</title>     <script type="text/javascript">         /*          * 组合的方式是属性通过伪造的方式实现,方法通过原型链的方式实现,注意

js匿名函数闭包

函数声明: function functionName(arg0,arg1){ //函数体 } 函数表达式: var functionName = function(arg0,arg1){ //函数体 } 函数声明和函数表达式之间的主要区别是前者会在代码执行前被加载到作用域中,而后者是在代码执行到那一行的时候才会有定义.另一个区别是函数声明会给函数指定一个名字,而函数表达式则创建一个匿名函数,然后将这个函数赋给一个变量 1 递归 递归函数是在一个函数通过名字调用自身的情况下构成的,例如: fun