JavaScript中实现继承的几种方式的使用和分析

首先来看一段代码:

  1. function Person(){
  2. }
  3. function Student(){
  4. }
  5. Student.prototype = Person.prototype;//第一种方式
  6. Student.prototype = new Person();//第二种方式
  7. Student.prototype = Object.create(Person.prototype)//第三种方式

第一种方式(不可取)

    可以实现继承,但是在改变Student的同时也会相应的改变Person,这很显然不是我们所需要的,所以此种继承方案不可取,是错误的。

第二种方式(原型继承)

    new Person()调用构造函数得到了一个Person的实例,并且这个实例指向了Person的prototype,所以这里实现了继承。但是就是因为调用了构造函数,所以这样可能会有问题,比如说,Person的构造函数是需要传递参数的function Person(name,age)等,那么在实例化的时候需要传递什么参数进去呢?很显然,不管传递什么都是很别扭的,所以此种方案使用的也不多。

第三种方式(Object.ceate):

    此方案是最为理想的方案。使用Object.create()方法创建一个空的对象,并且这个对象的原型指向了Person.prototype,这样我们既保证了我们可以继承Person.prototype上面的方法,并且Student.prototype又有自己的一个空的对象,所以Student的修改不会影响到原型链上面的方法。

    但是这里也有一个问题,就是Object.create()方法是在ES5之后才有的方法,那么在之前的版本我们可以用另一个方法来模拟一下代替:

  1. if(!Object.create){
  2. Object.create = function(proto){
  3. funtion F(){} //临时的空函数
  4. F.prototype = proto; //将空函数的prototype属性复制给我们想要作为原型的对象
  5. return new F; //new一个构造器,那么就会创建一个对象,这个对象的原型指向构造器的prototype
  6. }
  7. }


另外还有一种方式,使用call和apply:

  1. function Person(name,age,love){
  2. this.name=name;
  3. this.age=age;
  4. this.love=love;
  5. this.say=function say(){
  6. alert("姓名:"+name);
  7. }
  8. }
  9. //call方式
  10. function student(name,age){
  11. Person.call(this,name,age);
  12. }
  13. //apply方式
  14. function teacher(name,love){
  15. Person.apply(this,[name,love]);
  16. //Person.apply(this,arguments); //跟上句一样的效果,arguments
  17. }
  18. //call与aplly的异同:
  19. //1,第一个参数this都一样,指当前对象
  20. //2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章