Javascript继承机制(call、apply、prototype)
2013-07-08 09:11
579 查看
本文来自:http://blog.csdn.net/haijiaoxiaowu/article/details/5148657
Javascript的继承可以通过call、apply、prototype实现。
1、call:在子类中,用父类.call(this,arg0,arg1...)可以继承父类。注意call的位置,尽量在子类的第一行(js按顺序执行,放在后面可能对子类的其他属性、方法有影响。比如子类和父类有相同名字的方法,后面的覆盖前面的)。
[javascript]
view plaincopy
<html>
<head>
<title>call/apply/prototype test</title>
</head>
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
document.write("I am a person");
}
this.display = function() {
document.write(this.name + "-" + this.age);
}
}
//student类,继承自person
function student(name, age, no) {
person.call(this, name, age);//person中的this等于参数中的this,即student中的name和age
this.no = no;
this.display = function() {//覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
}
}
//创建person类
var p = new person("captain", 21);
p.display();//captain-21
p.say();//I am a person
//创建student类
var s = new student("captain", 21, "06281097")
s.display();//captain-21-06281097
s.say();//I am a person 继承了父类的方法
<script>
<body>
</body>
</html>
2、apply:在子类中,用父类.apply(this,args)可以继承父类(args为参数数组)。
[javascript]
view plaincopy
<html>
<head>
<title>call/apply/prototype test</title>
</head>
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
document.write("I am a person");
}
this.display = function() {
document.write(this.name + "-" + this.age);
}
}
//student类,继承自person
function student(name, age, no) {
person.apply(this, new Array(name, age));//与call不同的是,apply传递的是数组
this.no = no;
this.display = function() {//覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
}
}
//创建person类
var p = new person("captain", 21);
p.display();//captain-21
p.say();//I am a person
//创建student类
var s = new student("captain", 21, "06281097")
s.display();//captain-21-06281097
s.say();//I am a person 继承了父类的方法
<script>
<body>
</body>
</html>
3、prototype:类.prototype可以为类的所有实例添加属性或方法
[javascript]
view plaincopy
<html>
<head>
<title>call/apply/prototype test</title>
</head>
<script type="text/javascript">
//定义学生类(姓名、学好、年龄)
function student(name, no, age) {
this.name = name;
this.no = no;
this.age = age;
}
//学生实例
var captain = new student("captain", "06281097", 21);
//添加学校属性
student.prototype.school = null;
//为captain学生的学校属性赋值
captain.school = "BJTU";
//显示captain的学校
document.write(captain.school);
<script>
<body>
</body>
</html>
可见,通过prototype为类添加属性是不方便的,因为构造函数已经固定,实例化时无法对新加入的属性进行初始化。比如上例中的school属性,在新建student对象时,无法通过new student(name,no,age,school)进行初始化,很不方便。所以一般都用prototype为类添加方法。
使用prototype进行继承时,还存在着一些问题,比如下例中的student.prototype=new person();这里无法加入参数,因为一旦加入参数则所有的student实例的name和age都是固定的值。这种情况下就需要用call和prototype进行联合。
[javascript]
view plaincopy
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
document.write("I am a person");
}
this.display = function() {
document.write(this.name + "-" + this.age);
}
}
//student类
function student(name, age, no) {
this.no = no;
this.display = function() {//覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
}
}
student.prototype = new person();//student继承person(无法写带参构造函数)
//student.prototype = new person("name","age");//所有student实例的姓名都为name,年龄是age
var s = new student("captain", 21, "06281097");
s.say();//I am a person
s.display();//undefined-undefined-06281097
//student的name、age没有从参数中获得(两个属性要在person的构造行数中获得,但是prototype的构造函数无参)
<script>
4、call和prototype联合:解决了使用prototype不能使用带参构造函数的问题。在父类中,只定义属性字段,通过prototype为类添加方法。在子类中,通过call来调用父类带参构造函数,通过 子类.prototype=new 父类() 来继承父类的方法。
[javascript]
view plaincopy
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype.say = function() {//为person类添加say方法
document.write("I am a person");
};
person.prototype.display = function() {//为person类添加display方法
document.write(this.name + "-" + this.age);
};
//student类
function student(name, age, no) {
person.call(this,name,age);//可以获得父类构造方法(this.name=name;this.age=age;)
this.no = no;
}
student.prototype = new person();//没有此句,student类无法获得person的say/display方法
student.prototype.display = function() {//为student类添加display方法,并覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
};
var s = new student("captain", 21, "06281097");
s.say();//I am a person
s.display();//captain-21-06281097
<script>
5、继承之后的类型:用call继承,类型并没有发生变化;用prototype继承,类型也继承父类。详见下例
[javascript]
view plaincopy
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
}
//student类,继承自person(call)
function student(name, age, no) {
person.call(this, name, age);
this.no = no;
}
//programer类,继承自person(prototype)
function programer(name, age, sex) {
this.sex = sex;
}
programer.prototype = new person();
//man类,继承自person(prototype)
function man(name, age, height) {
person.call(this, name, age);
this.height = height;
this
}
man.prototype.say = function() {
alert(this.name);
};
//创建person实例
var p = new person("captain", 21);
//创建student实例
var s = new student("captain", 21, "06281097");
//创建programer实例
var g = new programer("captain", 21, "男");
//创建man实例
var m = new man("captain", 21, 176);
//判断类型(typeof返回全是object,所以用instanceof)
alert(s instanceof person);//false 使用call并不是完全的继承
alert(s instanceof student);//true
alert(g instanceof person);//true
alert(g instanceof programer);//true
alert(m instanceof person);//false
//只有使用prototype添加父类的构造函数,才能在意义上完全继承person
alert(m instanceof man);//true
<script>
Javascript的继承可以通过call、apply、prototype实现。
1、call:在子类中,用父类.call(this,arg0,arg1...)可以继承父类。注意call的位置,尽量在子类的第一行(js按顺序执行,放在后面可能对子类的其他属性、方法有影响。比如子类和父类有相同名字的方法,后面的覆盖前面的)。
[javascript]
view plaincopy
<html>
<head>
<title>call/apply/prototype test</title>
</head>
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
document.write("I am a person");
}
this.display = function() {
document.write(this.name + "-" + this.age);
}
}
//student类,继承自person
function student(name, age, no) {
person.call(this, name, age);//person中的this等于参数中的this,即student中的name和age
this.no = no;
this.display = function() {//覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
}
}
//创建person类
var p = new person("captain", 21);
p.display();//captain-21
p.say();//I am a person
//创建student类
var s = new student("captain", 21, "06281097")
s.display();//captain-21-06281097
s.say();//I am a person 继承了父类的方法
<script>
<body>
</body>
</html>
2、apply:在子类中,用父类.apply(this,args)可以继承父类(args为参数数组)。
[javascript]
view plaincopy
<html>
<head>
<title>call/apply/prototype test</title>
</head>
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
document.write("I am a person");
}
this.display = function() {
document.write(this.name + "-" + this.age);
}
}
//student类,继承自person
function student(name, age, no) {
person.apply(this, new Array(name, age));//与call不同的是,apply传递的是数组
this.no = no;
this.display = function() {//覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
}
}
//创建person类
var p = new person("captain", 21);
p.display();//captain-21
p.say();//I am a person
//创建student类
var s = new student("captain", 21, "06281097")
s.display();//captain-21-06281097
s.say();//I am a person 继承了父类的方法
<script>
<body>
</body>
</html>
3、prototype:类.prototype可以为类的所有实例添加属性或方法
[javascript]
view plaincopy
<html>
<head>
<title>call/apply/prototype test</title>
</head>
<script type="text/javascript">
//定义学生类(姓名、学好、年龄)
function student(name, no, age) {
this.name = name;
this.no = no;
this.age = age;
}
//学生实例
var captain = new student("captain", "06281097", 21);
//添加学校属性
student.prototype.school = null;
//为captain学生的学校属性赋值
captain.school = "BJTU";
//显示captain的学校
document.write(captain.school);
<script>
<body>
</body>
</html>
可见,通过prototype为类添加属性是不方便的,因为构造函数已经固定,实例化时无法对新加入的属性进行初始化。比如上例中的school属性,在新建student对象时,无法通过new student(name,no,age,school)进行初始化,很不方便。所以一般都用prototype为类添加方法。
使用prototype进行继承时,还存在着一些问题,比如下例中的student.prototype=new person();这里无法加入参数,因为一旦加入参数则所有的student实例的name和age都是固定的值。这种情况下就需要用call和prototype进行联合。
[javascript]
view plaincopy
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
document.write("I am a person");
}
this.display = function() {
document.write(this.name + "-" + this.age);
}
}
//student类
function student(name, age, no) {
this.no = no;
this.display = function() {//覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
}
}
student.prototype = new person();//student继承person(无法写带参构造函数)
//student.prototype = new person("name","age");//所有student实例的姓名都为name,年龄是age
var s = new student("captain", 21, "06281097");
s.say();//I am a person
s.display();//undefined-undefined-06281097
//student的name、age没有从参数中获得(两个属性要在person的构造行数中获得,但是prototype的构造函数无参)
<script>
4、call和prototype联合:解决了使用prototype不能使用带参构造函数的问题。在父类中,只定义属性字段,通过prototype为类添加方法。在子类中,通过call来调用父类带参构造函数,通过 子类.prototype=new 父类() 来继承父类的方法。
[javascript]
view plaincopy
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype.say = function() {//为person类添加say方法
document.write("I am a person");
};
person.prototype.display = function() {//为person类添加display方法
document.write(this.name + "-" + this.age);
};
//student类
function student(name, age, no) {
person.call(this,name,age);//可以获得父类构造方法(this.name=name;this.age=age;)
this.no = no;
}
student.prototype = new person();//没有此句,student类无法获得person的say/display方法
student.prototype.display = function() {//为student类添加display方法,并覆盖了父类的方法
document.write(this.name + "-" + this.age + "-" + this.no);
};
var s = new student("captain", 21, "06281097");
s.say();//I am a person
s.display();//captain-21-06281097
<script>
5、继承之后的类型:用call继承,类型并没有发生变化;用prototype继承,类型也继承父类。详见下例
[javascript]
view plaincopy
<script type="text/javascript">
//person类
function person(name, age) {
this.name = name;
this.age = age;
}
//student类,继承自person(call)
function student(name, age, no) {
person.call(this, name, age);
this.no = no;
}
//programer类,继承自person(prototype)
function programer(name, age, sex) {
this.sex = sex;
}
programer.prototype = new person();
//man类,继承自person(prototype)
function man(name, age, height) {
person.call(this, name, age);
this.height = height;
this
}
man.prototype.say = function() {
alert(this.name);
};
//创建person实例
var p = new person("captain", 21);
//创建student实例
var s = new student("captain", 21, "06281097");
//创建programer实例
var g = new programer("captain", 21, "男");
//创建man实例
var m = new man("captain", 21, 176);
//判断类型(typeof返回全是object,所以用instanceof)
alert(s instanceof person);//false 使用call并不是完全的继承
alert(s instanceof student);//true
alert(g instanceof person);//true
alert(g instanceof programer);//true
alert(m instanceof person);//false
//只有使用prototype添加父类的构造函数,才能在意义上完全继承person
alert(m instanceof man);//true
<script>
相关文章推荐
- Javascript继承机制(call、apply、prototype)
- 基于JavaScript实现继承机制之调用call()与apply()的方法详解
- javascript 中的继承实现, call,apply,prototype,构造函数
- JavaScript实现继承机制(2)——调用call()与apply()方法
- 基于JavaScript实现继承机制之调用call()与apply()的方法详解
- javascript 对象基础 继承机制实例 call() apply 方法!
- JavaScript原型、函数伪装(apply,call)、继承
- [转载]js中继承的几种用法总结(apply,call,prototype)
- JavaScript继承机制之prototype, __proto__, constructor
- js中继承的几种用法总结(apply,call,prototype)
- Javascript中的prototype和继承机制
- 由JavaScript中call()方法引发的对面向对象继承机制call的思考
- javascript 之 prototype继承机制
- javascript继承--call()和apply实现继承
- js中继承的几种用法apply,call,prototype
- js中继承的几种用法总结(apply,call,prototype)
- JavaScript:prototype&apply&call
- JavaScript中 apply/call 与面向对象语言中继承关系的联系和区别
- js中继承的几种用法总结(apply,call,prototype)
- JavaScript:prototype&apply&call