JavaScript学习13 JavaScript中的继承
继承第一种方式:对象冒充
<script type="text/javascript"> //继承第一种方式:对象冒充 function Parent(username) //父类对象 { this.username = username; //下面的代码最关键的部分就是将子对象的this传递给了父对象 this.sayHello = function() { alert(this.username); } } function Child(username, password) //子类对象 { //下面三行代码是最关键的代码 this.method = Parent; //定义method属性,指向Parent,即指向了上面的构造函数 this.method(username);//把username传递过去,调用构造函数,此时Parent函数体中的this即当前的Child对象 delete this.method; //删掉method属性,因为Child已经具备了Parent的属性和方法 //下面可以增加一些子类特有的属性和方法 this.password = password; this.sayWorld = function() { alert(this.password); } } //生成这两个类的对象 var parent = new Parent("zhangsan"); var child = new Child("lisi", "1234"); parent.sayHello(); child.sayHello(); child.sayWorld(); </script>
使用这种方式实现继承的时候,JS可以实现多重的继承,但是有时候会造成一些干扰,比如同名方法的覆盖,所以不太推荐使用多继承。
继承第二种方式:call方法方式
call方法是定义在Function对象中的方法,因此我们定义的每个函数都有该方法。
可以通过函数名来调用call方法,call方法的第一个参数会被传递给函数中的this,从第二个参数开始,逐一赋值给函数中的参数。
call方法:
<script type="text/javascript"> //call方法方式,Function对象中的方法 function test(str, str2) { alert(this.name + ", " + str + ", " + str2); } var object = new Object(); object.name = "zhangsan"; //test.call相当于调用了test函数 test.call(object, "shengsiyuan", "hello"); //将object赋给了this //第一个参数赋给this,后面的参数逐次赋给方法参数 </script>
call方法实现继承:
<script type="text/javascript"> //使用call方式实现对象的继承 function Parent(username) { this.username = username; this.sayHello = function() { alert(this.username); } } function Child(username, password) { Parent.call(this, username);//这样语句很关键,等价于对象冒充中的三行语句 //执行之后子类就具有了基类的属性和方法 //子对象的新增属性和方法 this.password = password; this.sayWorld = function() { alert(this.password); } } var parent = new Parent("zhangsan"); var child = new Child("lisi", "123"); parent.sayHello(); child.sayHello(); child.sayWorld(); </script>
继承第三种方式:apply方法方式
apply和call一样,都是定义在Function对象里面的。
<script type="text/javascript"> //使用apply方法实现对象继承 function Parent(username) { this.username = username; this.sayHello = function() { alert(this.username); } } function Child(username, password) { Parent.apply(this, new Array(username));//apply方法方式实现继承,后面的参数以数组的形式传入 this.password = password; this.sayWorld = function() { alert(this.password); } } var parent = new Parent("zhangsan"); var child = new Child("lisi", "123"); parent.sayHello(); child.sayHello(); child.sayWorld(); </script>
继承第四种方式:原型链方式
<script type="text/javascript"> //使用原型链(prototype chain)方式实现对象继承 function Parent() { } Parent.prototype.hello = "hello"; Parent.prototype.sayHello = function() { alert(this.hello); } function Child() { } Child.prototype = new Parent();//子类具有父类的属性和方法 //扩展属性 Child.prototype.world = "world"; Child.prototype.sayWorld = function() { alert(this.world); } var child = new Child(); child.sayHello(); child.sayWorld(); </script>
原型链的方式,缺点是无法给构造函数传递参数。
继承的第五种方式:混合方式
这种方式是对原型链方式的一种改进,使得可以向构造函数传递参数。
这种方式是比较推荐的一种方式。
<script type="text/javascript"> //使用混合方式实现对象继承(推荐) //父对象 function Parent(hello) { this.hello = hello; } Parent.prototype.sayHello = function() { alert(this.hello); } //子对象 function Child(hello, world) { Parent.call(this, hello);//通过call实现属性的继承 this.world = world;//新增加的属性 } Child.prototype = new Parent();//通过原型链实现方法的继承 Child.prototype.sayWorld = function() { alert(this.world); } var child = new Child("hello", "world"); child.sayHello(); child.sayWorld(); </script>
实例
<script type="text/javascript"> function Shape(edge) { this.edge = edge;//属性,多少条边,通过构造函数的方式定义 } Shape.prototype.getArea = function()//通过原型的方式来定义方法 { return -1;//基类返回一个没有意义的值 } Shape.prototype.getEdge = function() { return this.edge; } //定义子对象Triangle function Triangle(bottom, height) { Shape.call(this, 3); //Triangle的属性 this.bottom = bottom; this.height = height; } Triangle.prototype = new Shape();//继承Shaple中的所有方法 Triangle.prototype.getArea = function()//重写方法 { return 0.5 * this.bottom * this.height; } var triangle = new Triangle(10, 4); //alert(triangle.getEdge()); //alert(triangle.getArea()); //另一个子类:四边形 function Rectangle(bottom, height) { Shape.call(this, 4); this.bottom = bottom; this.height = height; } Rectangle.prototype = new Shape();//通过原型继承父类的所有方法 Rectangle.prototype.getArea = function()//覆写方法 { return this.bottom * this.height; } var rectangle = new Rectangle(20, 40); alert(rectangle.getEdge()); alert(rectangle.getArea()); </script>
参考资料
圣思园张龙老师Java Web系列视频教程。