<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title> <script type="application/javascript"> //基于伪装的继承
/**
* call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
*/
function Parent(){
this.color = ["red","blue"];
this.name = "Leon";
} function Child(){
//在Child中的this明显应该是指向Child的对象
//当调用Parent方法的时候,而且this有时指向了Child
//此时就等于在这里完成this.color = ["red","blue"]
//也就是等于在Child中有了this.color的属性,这样也就变相的完成了集成 Parent.call(this); //这种调用方式,Parent的上下文是Parent对象,根本无法实现继承
//Parent();
} var c1 = new Child();
c1.color.push("green");
console.info(c1.color); //["red", "blue", "green"]
var c2 = new Child();
console.info(c2.color); //["red", "blue"]
console.info(c2.name); //Leon function Parent2(name){
this.color = ["red","blue"];
this.name = name;
} function Child2(name , age){
//在Child中的this明显应该是指向Child的对象
//当调用Parent方法的时候,而且this有时指向了Child
//此时就等于在这里完成this.color = ["red","blue"]
//也就是等于在Child中有了this.color的属性,这样也就变相的完成了集成 this.age = age;
Parent2.call(this , name); //这种调用方式,Parent的上下文是Parent对象,根本无法实现继承
//Parent();
} var c3 = new Child2("Leon" , 12);
c3.color.push("green");
console.info(c3.color); //["red", "blue", "green"]
console.info(c3.name + " " + c3.age); //Leon 12
var c4 = new Child2("Ada" , 22);
console.info(c4.color); //["red", "blue"]
console.info(c4.name + " " + c4.age); //Ada 22 //这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4);
// 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。
function add(a,b){
console.info(a+b);
}
function sub(a,b){
console.info(a-b);
} add.call(sub,3,1); // //call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat
function Animal(){
this.name = "Animal";
this.showName = function(){
console.info(this.name);
}
} function Cat(){
this.name = "Cat";
} var animal = new Animal();
var cat = new Cat(); //通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
//输入结果为"Cat"
animal.showName.call(cat,","); //Cat
animal.showName.apply(cat,[]);//Cat // Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.
function Animal2(name){
this.name = name;
this.showName = function(){
console.info(this.name);
}
} function Cat2(name){
Animal2.call(this, name);
} var cat2 = new Cat2("Black Cat");
cat2.showName();//Black Cat //
//实现多继承
// 很简单,使用两个 call 就实现多重继承了
// 当然,js的继承还有其他方法,例如使用原型链,这个不属于本文的范畴,只是在此说明call 的用法。
// 说了call ,当然还有 apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments
// 还有 callee,caller..
function Class10(){
this.showSub = function(a,b){
console.info(a-b);
}
} function Class11() {
this.showAdd = function(a,b){
console.info(a+b);
}
} function Class2(){
Class10.call(this);
Class11.call(this);
} var c2 = new Class2();
c2.showSub(1,2);
c2.showAdd(1,2); </script> </head>
<body> </body>
</html>

基于伪造继承问题:

 <!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title> <script type="application/javascript"> //基于伪造的继承存在问题: function Parent2(name){
this.color = ["red","blue"];
this.name = name;
} //由于使用伪造的方式,不会完成Child的原形指向Parent,所以say方法不存在,
18 //解决方法:将该say方法放入到Parent2中使用this来创建,
19 // 但是又有新问题:每个对象中又存在say方法,这样空间占用太大,所有也不会单独的方式实现
Parent2.prototype.say = function(){
console.info(this.name);
} function Child2(name , age){
//在Child中的this明显应该是指向Child的对象
//当调用Parent方法的时候,而且this有时指向了Child
//此时就等于在这里完成this.color = ["red","blue"]
//也就是等于在Child中有了this.color的属性,这样也就变相的完成了集成 this.age = age;
/*
* 使用伪造的方式就可以吧自雷的构造函数参数传递到父类中
*/
Parent2.call(this , name); //这种调用方式,Parent的上下文是Parent对象,根本无法实现继承
//Parent();
} var c3 = new Child2("Leon" , 12);
c3.color.push("green");
console.info(c3.color); //["red", "blue", "green"]
console.info(c3.name + " " + c3.age); //Leon 12
c3.say(); //异常: Uncaught TypeError: c3.say is not a function
var c4 = new Child2("Ada" , 22);
console.info(c4.color); //["red", "blue"]
console.info(c4.name + " " + c4.age); //Ada 22 </script> </head>
<body> </body>
</html>

解决伪造继承的问题;

 <!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title> <script type="application/javascript"> /**
* 组合的实现方式是属性通过伪造的方法实现,方法通过原形连的方式实现
*
*/ function Parent(name){
this.color = ["red","blue"];
this.name = name;
} Parent.prototype.ps = function(){
console.info(this.name + "[ " + this.color + "]");
} function Child(name , age){
Parent.call(this,name);
this.age = age;
} Child.prototype = new Parent();
Child.prototype.say = function(){
console.info(this.name + " " + this.age + " " + this.color);
} var c1 = new Child("Leon" , 22) ;
c1.color.push("green");
c1.say(); //Leon 22 red,blue,green
c1.ps(); //Leon[ red,blue,green]
var c2 = new Child("Ada" , 23) ;
c2.say(); //Ada 23 red,blue
</script> </head>
<body> </body>
</html>

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

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

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

  2. 前端小课堂 js:函数的创建方式及区别

    js 函数的创建大体有这几种方式: -1-函数表达式(函数字面量): 说白了就是把一个函数赋值给了一个变量. var fun1 = function(index){ alert(index); } f ...

  3. js自调用函数的实现方式

    我们知道,js中定义自调用函数通常使用下列方式: (function () { alert("函数2"); })(); 事实上,使用括号包裹定义函数体,解析器将会以函数表达式的方式 ...

  4. js 函数定义的方式

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

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

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

  6. js的面向对象的程序设计之理解继承

    来自<javascript高级程序设计 第三版:作者Nicholas C. Zakas>的学习笔记(六) 先来解析下标题——对象和继承~ 一.对象篇 ECMA-262把对象的定义为:&qu ...

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

    js 对象深复制,创建对象和继承.主要参考高级编程第三版,总结网上部分资料和自己的代码测试心得.每走一小步,就做一个小结. 1.对象/数组深复制 一般的=号传递的都是对象/数组的引用,如在控制台输入 ...

  8. JS 精粹( 函数)

    函数是对象,它与其它对象唯一的不同是它可以调用.函数可实现:代码复用.信息隐藏.代码组合调用. 建立函数时会建立:上下文.调用函数的代码.每个函数(除Function.prototype)都会有一个原 ...

  9. JS中OOP之模拟封装和继承和this指向详解

    大家好,今天我带大家学习一下js的OOP, 大家都知道,面向对象有三个基本特征,继承,封装和多态,面向对象的语言有那么几种,C++,PHP,JAVA等,而功能强大的JS可以模拟实现面向对象的两大特征, ...

随机推荐

  1. 【转】Linux设备驱动之Ioctl控制

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275372.html 大部分驱动除了需要具备读写设备的能力之外,还需要具备对硬件控制的能 ...

  2. Android使用绘图Path总结

    Path作为Android中一种相对复杂的绘图方式,官方文档中的有些解释并不是很好理解,这里作一个相对全面一些的总结,供日后查看,也分享给大家,共同进步. 1.基本绘图方法 addArc(RectF ...

  3. web app 页面旋转整体样式问题

    $(window).bind("orientationchange", function (event) { if (event.orientation) { //portrait ...

  4. Sde表结构分析

    原文 Sde表结构分析 今天开始想分析一下sde的表结构,希望能够弄明白sde一个要素类的每个Feature是如何存储的. 弄ArcSDE的人都知道,ArcSDE内一个要素类在关系数据库(以MS SQ ...

  5. eclipse 报错汇总

    1.Eclipse 启动时,报错: Fail to create the java virtual machine   已解决.方法:eclipse.ini 中-vmargs-Dosgi.requir ...

  6. Android百度地图开发(四)线路搜索

    一.标注驾车线路搜索 1.首先需要定义一个起点和一个终点 // 定义一个起始点和终点 private MKPlanNode start; private MKPlanNode end; 2.实例化地图 ...

  7. JDT入门

    1.打开Java类型 要打开一个Java类或Java接口以进行编辑,可以执行以下操作之一: 在编辑器中所显示的源代码里选择所要编辑的Java类或Java接口的名字(或者简单地将插入光标定位到所要编辑的 ...

  8. 我的格斗梦——张龙海(R.J)谈游戏动画师职业(转)

    编者按:他是一个生在东北,祖藉却是韩国的年轻人.从小生性好动的他觉得上课 学习十分枯燥,所以高中没毕业便辍学在家.但他仍是一个喜欢动漫.游戏的年轻人,因为热爱所以他用父母给的钱开始了求学之路,在之后的 ...

  9. (转载)OC学习篇之---协议的概念和用法

    在前一篇文章中我们介绍了OC中类的延展,这一篇文章我们在来看一下OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Jav ...

  10. c语言的几个重要知识点

      内存结构 这是核心中的核心,请仔细看完,充分理解,否则请不要看下一节内容. 每个程序一启动都有一个大小为4GB的内存,这个内存叫虚拟内存,是概念上的,真正能用到的,只是很小一部分,一般也就是在几百 ...