您的位置:首页 > Web前端 > JavaScript

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

2016-05-03 10:40 232 查看
<!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); //4

//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>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: