JavaScript中继承的实现方法--详解

时间:2023-03-08 23:21:10
JavaScript中继承的实现方法--详解

最近看《JavaScript王者归来》中关于实现继承的方法,做了一些小总结:

JavaScript中要实现继承,其实就是实现三层含义:
1、子类的实例可以共享父类的方法;
2、子类可以覆盖父类的方法或者扩展新的方法;
3、子类和父类都是子类实例的“类型”。

JavaScript中,并不直接从语法上支持继承,但是可以通过模拟的方法来实现继承,以下是关于实现继承的几种方法的总结:
1、构造继承法
2、原型继承法
3、实例继承法
4、拷贝继承法

1、构造继承法:
在子类中执行父类的构造函数。

 1JavaScript中继承的实现方法--详解<SCRIPT LANGUAGE="JavaScript">
 2JavaScript中继承的实现方法--详解  <!--
 3JavaScript中继承的实现方法--详解        function dwn(s)
 4JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 5JavaScript中继承的实现方法--详解                document.write(s+'<br/>');
 6JavaScript中继承的实现方法--详解        }
 7JavaScript中继承的实现方法--详解
 8JavaScript中继承的实现方法--详解        //定义一个Collection类型
 9JavaScript中继承的实现方法--详解        function Collection(size)
10JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
11JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解                this.size = function()JavaScript中继承的实现方法--详解{return size};  //公有方法,可以被继承
12JavaScript中继承的实现方法--详解        }
13JavaScript中继承的实现方法--详解
14JavaScript中继承的实现方法--详解        //定义一个_Collection类型
15JavaScript中继承的实现方法--详解        function _Collection(_size)
16JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
17JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解                this._size = function()JavaScript中继承的实现方法--详解{return _size};  //公有方法,可以被继承
18JavaScript中继承的实现方法--详解        }
19JavaScript中继承的实现方法--详解
20JavaScript中继承的实现方法--详解        Collection.prototype.isEmpty = function()  //静态方法,不能被继承
21JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
22JavaScript中继承的实现方法--详解                return this.size() == 0;
23JavaScript中继承的实现方法--详解        }
24JavaScript中继承的实现方法--详解
25JavaScript中继承的实现方法--详解        //定义一个ArrayList类型,它“继承”Colleciton类型
26JavaScript中继承的实现方法--详解        function ArrayList()
27JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
28JavaScript中继承的实现方法--详解                var m_elements = [];  //私有成员,不能被继承
29JavaScript中继承的实现方法--详解                m_elements = Array.apply(m_elements,arguments);
30JavaScript中继承的实现方法--详解
31JavaScript中继承的实现方法--详解                //ArrayList类型继承Colleciton
32JavaScript中继承的实现方法--详解                this.base = Collection;
33JavaScript中继承的实现方法--详解                this.base.call(this,m_elements.length);
34JavaScript中继承的实现方法--详解
35JavaScript中继承的实现方法--详解                this.base = _Collection;                   //可以实现多态继承
36JavaScript中继承的实现方法--详解                this.base.call(this,m_elements.length);    
37JavaScript中继承的实现方法--详解
38JavaScript中继承的实现方法--详解                this.add = function()
39JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解                JavaScript中继承的实现方法--详解{
40JavaScript中继承的实现方法--详解                        return m_elements.push.apply(m_elements,arguments);        
41JavaScript中继承的实现方法--详解                }
42JavaScript中继承的实现方法--详解
43JavaScript中继承的实现方法--详解                this.toArray = function()
44JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解                JavaScript中继承的实现方法--详解{
45JavaScript中继承的实现方法--详解                        return m_elements;
46JavaScript中继承的实现方法--详解                }
47JavaScript中继承的实现方法--详解        }
48JavaScript中继承的实现方法--详解
49JavaScript中继承的实现方法--详解        ArrayList.prototype.toString = function()
50JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
51JavaScript中继承的实现方法--详解                return this.toArray().toString();
52JavaScript中继承的实现方法--详解        }
53JavaScript中继承的实现方法--详解
54JavaScript中继承的实现方法--详解        //定义一个SortedList类型,它继承ArrayList类型
55JavaScript中继承的实现方法--详解        function SortedList()
56JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
57JavaScript中继承的实现方法--详解                //SortedList类型继承ArrayList
58JavaScript中继承的实现方法--详解                this.base = ArrayList;
59JavaScript中继承的实现方法--详解                this.base.apply(this,arguments);
60JavaScript中继承的实现方法--详解
61JavaScript中继承的实现方法--详解                this.sort = function()
62JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解                JavaScript中继承的实现方法--详解{
63JavaScript中继承的实现方法--详解                        var arr = this.toArray();
64JavaScript中继承的实现方法--详解                        arr.sort.apply(arr,arguments);
65JavaScript中继承的实现方法--详解                }
66JavaScript中继承的实现方法--详解        }
67JavaScript中继承的实现方法--详解
68JavaScript中继承的实现方法--详解        //构造一个ArrayList
69JavaScript中继承的实现方法--详解        var a = new ArrayList(1,2,3);
70JavaScript中继承的实现方法--详解        dwn(a);          //1,2,3
71JavaScript中继承的实现方法--详解        dwn(a.size());   //3 a从Collection继承了size()方法
72JavaScript中继承的实现方法--详解        dwn(a.isEmpty);  //undefined 但是a没有继承到isEmpty()方法
73JavaScript中继承的实现方法--详解
74JavaScript中继承的实现方法--详解        dwn(a._size());  //3 可以实现多态继承
75JavaScript中继承的实现方法--详解
76JavaScript中继承的实现方法--详解        //构造一个SortedList
77JavaScript中继承的实现方法--详解        var b = new SortedList(3,1,2);
78JavaScript中继承的实现方法--详解        dwn(b.toArray());
79JavaScript中继承的实现方法--详解        b.add(4,0);    //b 从ArrayList继承了add()方法
80JavaScript中继承的实现方法--详解        dwn(b.toArray());  //b从ArrayList继承了toArray()方法
81JavaScript中继承的实现方法--详解        b.sort();      //b自己实现sort()方法
82JavaScript中继承的实现方法--详解        dwn(b.toArray());
83JavaScript中继承的实现方法--详解        dwn(b);
84JavaScript中继承的实现方法--详解        dwn(b.size());   //b从Collection继承了size()方法
85JavaScript中继承的实现方法--详解  //-->
86JavaScript中继承的实现方法--详解  </SCRIPT>

2、原型继承法:
JavaScript是一种基于原型的语言。
要了解什么是“原型继承法”,先了解一下prototype的特性:prototype的最大特性是能够让对象实例共享原型对象的属性,因此如果把某个对象作为一个类型的原型,那么我们说这个类型的所有实例都一这个对象为原型。这个时候,实际上这个对象的类型也可以作为那些以这个对象为原型的实例的类型。
假如:Point类的对象作为Point2D类型的原型(Point2D.prototype = new Point(2)),那么说Point2D的所有实例都是以Point类的对象为原型。此时,实际上Point类就可以作为Point2D类型的对象的类型(相当于Point2D类型“继承”了Point类型)。
见例:

 1JavaScript中继承的实现方法--详解  <SCRIPT LANGUAGE="JavaScript">
 2JavaScript中继承的实现方法--详解  <!--
 3JavaScript中继承的实现方法--详解        function dwn(s)
 4JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 5JavaScript中继承的实现方法--详解                document.write(s+"<br/>");
 6JavaScript中继承的实现方法--详解        }
 7JavaScript中继承的实现方法--详解
 8JavaScript中继承的实现方法--详解        function Point(dimension)  //定义一个Point类
 9JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
10JavaScript中继承的实现方法--详解                this.dimension = dimension;
11JavaScript中继承的实现方法--详解        }
12JavaScript中继承的实现方法--详解
13JavaScript中继承的实现方法--详解        Point.prototype.distance = function() //静态方法,可以被继承
14JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
15JavaScript中继承的实现方法--详解                return this.dimension*2;
16JavaScript中继承的实现方法--详解        }
17JavaScript中继承的实现方法--详解
18JavaScript中继承的实现方法--详解        function Point2D(x,y)    //定义一个Point2D类
19JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
20JavaScript中继承的实现方法--详解                this.x = x;
21JavaScript中继承的实现方法--详解                this.y = y;
22JavaScript中继承的实现方法--详解        }
23JavaScript中继承的实现方法--详解
24JavaScript中继承的实现方法--详解        Point2D.prototype = new Point(2);   //运行“原型继承法”使Point2D继承Point
25JavaScript中继承的实现方法--详解
26JavaScript中继承的实现方法--详解        function Point3D(x,y,z)   //定义Point3D类
27JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
28JavaScript中继承的实现方法--详解                this.x = x;
29JavaScript中继承的实现方法--详解                this.y = y;
30JavaScript中继承的实现方法--详解                this.z = z;
31JavaScript中继承的实现方法--详解        }
32JavaScript中继承的实现方法--详解
33JavaScript中继承的实现方法--详解        Point3D.prototype = new Point(3);   //Point3D继承Point类
34JavaScript中继承的实现方法--详解
35JavaScript中继承的实现方法--详解        var p2 = new Point2D(1,2);  //构造一个Point2D对象
36JavaScript中继承的实现方法--详解
37JavaScript中继承的实现方法--详解        var p3 = new Point3D(1,2,3); //构造一个Point3D对象
38JavaScript中继承的实现方法--详解
39JavaScript中继承的实现方法--详解        dwn(p2.dimension);            //2
40JavaScript中继承的实现方法--详解        dwn(p3.dimension);            //3
41JavaScript中继承的实现方法--详解        dwn(p2.distance());           //4 可以继承静态方法
42JavaScript中继承的实现方法--详解        dwn(p3.distance());           //6 可以继承静态方法
43JavaScript中继承的实现方法--详解
44JavaScript中继承的实现方法--详解        dwn(p2 instanceof Point2D);   //p2是Point2D对象
45JavaScript中继承的实现方法--详解        dwn(p2 instanceof Point);     //Point2D继承Point,p2是Point对象
46JavaScript中继承的实现方法--详解
47JavaScript中继承的实现方法--详解        dwn(p3 instanceof Point3D);   //p3是Point3D对象
48JavaScript中继承的实现方法--详解        dwn(p3 instanceof Point);     //Point3D继承Point,p3是Point对象
49JavaScript中继承的实现方法--详解
50JavaScript中继承的实现方法--详解  //-->
51JavaScript中继承的实现方法--详解  </SCRIPT>

3、实例继承法
   构造继承法和原型继承法各有各的缺点,如:
   构造继承法没有办法继承类型的静态方法,因此它无法很好的继承JavaScript的核心对象。
   原型继承法虽然可以继承静态方法,但是依然无法很好地继承核心对象中的不可枚举方法。
   其中,javascript核心对象包括: 
   Array  表述数组。  
   Boolean  表述布尔值。 
   Date  表述日期。 
   Function  指定了一个可编译为函数的字符串 JavaScript 代码。 
   Math  提供了基本的数学常量和函数;如其 PI 属性包含了π的值。 
   Number  表述实数数值。 
   Object  包含了由所有 JavaScript 对象共享的基本功能。 
   RegExp  表述了一个正则表达式;同时包含了由所有正则表达式对象的共享的静态属性。 
   String  表述了一个 JavaScript 字符串。
 (1)构造继承法的局限性:

 1JavaScript中继承的实现方法--详解  <SCRIPT LANGUAGE="JavaScript">
 2JavaScript中继承的实现方法--详解  <!--
 3JavaScript中继承的实现方法--详解        function MyDate()
 4JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 5JavaScript中继承的实现方法--详解                this.base = Date;
 6JavaScript中继承的实现方法--详解                this.base.apply(this,arguments);
 7JavaScript中继承的实现方法--详解        }
 8JavaScript中继承的实现方法--详解
 9JavaScript中继承的实现方法--详解        var date = new MyDate();
10JavaScript中继承的实现方法--详解        alert(date.toGMTSring());   //对象不支持此方法或属性
11JavaScript中继承的实现方法--详解        //核心对象(Date)的某些方法不能被构造继承,原因是核心对象并不像我们自定义的一般对象那样在构造函数里进行赋值或初始化操作。
12JavaScript中继承的实现方法--详解  //--> 

(2)原型继承的局限性

 1JavaScript中继承的实现方法--详解  <SCRIPT LANGUAGE="JavaScript">
 2JavaScript中继承的实现方法--详解  <!--
 3JavaScript中继承的实现方法--详解        function MyDate()
 4JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 5JavaScript中继承的实现方法--详解
 6JavaScript中继承的实现方法--详解        }
 7JavaScript中继承的实现方法--详解        MyDate.prototype = new Date();
 8JavaScript中继承的实现方法--详解        var date = new MyDate();
 9JavaScript中继承的实现方法--详解        alert(date.toGMTSring());    //'[object]不是日期对象'
10JavaScript中继承的实现方法--详解  //-->
11JavaScript中继承的实现方法--详解  </SCRIPT>

以上说明了“构造继承法”和“原型继承法”的局限性(局限之一:不能很好的继承核心对象),下面介绍如何用实例继承法来继承核心对象。

在介绍之前首先了解以下关于构造函数:
构造函数通常没有返回值,它们只是初始化由this值传递进来的对象,并且什么也不返回。如果函数有返回值,被返回的对象就成了new表达式的值。

 1JavaScript中继承的实现方法--详解  <SCRIPT LANGUAGE="JavaScript">
 2JavaScript中继承的实现方法--详解  <!--
 3JavaScript中继承的实现方法--详解        function dwn(s)
 4JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 5JavaScript中继承的实现方法--详解                document.write(s+'<br/>');
 6JavaScript中继承的实现方法--详解        }
 7JavaScript中继承的实现方法--详解        function MyDate()
 8JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 9JavaScript中继承的实现方法--详解                var instance = new Date();   //instance是一个新创建的日期对象
10JavaScript中继承的实现方法--详解                instance.printDate = function()  //对日期对象instance扩展printDate()方法
11JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解                JavaScript中继承的实现方法--详解{
12JavaScript中继承的实现方法--详解                        dwn(instance.toLocaleString());
13JavaScript中继承的实现方法--详解                }
14JavaScript中继承的实现方法--详解                return instance;   //将instance作为构造函数的返回值返回
15JavaScript中继承的实现方法--详解        }
16JavaScript中继承的实现方法--详解
17JavaScript中继承的实现方法--详解        var date = new MyDate();
18JavaScript中继承的实现方法--详解        dwn(date.toGMTString());
19JavaScript中继承的实现方法--详解        date.printDate();    
20JavaScript中继承的实现方法--详解        dwn(date instanceof MyDate);  //false
21JavaScript中继承的实现方法--详解        dwn(date instanceof Date);    //true
22JavaScript中继承的实现方法--详解        //对象的构造函数将会是实际构造的对象的构造函数(new Date()),而不是类型本身的构造函数(new MyDate())
23JavaScript中继承的实现方法--详解  //-->
24JavaScript中继承的实现方法--详解  </SCRIPT>

 4、拷贝继承法

拷贝继承法是通过对象属性的拷贝来实现继承。

 1JavaScript中继承的实现方法--详解  <script language="JavaScript">
 2JavaScript中继承的实现方法--详解        function Point(dimension)
 3JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 4JavaScript中继承的实现方法--详解                this.dimension = dimension;
 5JavaScript中继承的实现方法--详解        }
 6JavaScript中继承的实现方法--详解
 7JavaScript中继承的实现方法--详解        var Point2D = function(x,y)
 8JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
 9JavaScript中继承的实现方法--详解                this.x = x;
10JavaScript中继承的实现方法--详解                this.y = y;
11JavaScript中继承的实现方法--详解        }
12JavaScript中继承的实现方法--详解
13JavaScript中继承的实现方法--详解    Point2D.extend = function()
14JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解        JavaScript中继承的实现方法--详解{
15JavaScript中继承的实现方法--详解            var p = new Point(2);
16JavaScript中继承的实现方法--详解            for(var each in p)   //将对象的属性进行一对一的复制。
17JavaScript中继承的实现方法--详解JavaScript中继承的实现方法--详解            JavaScript中继承的实现方法--详解{
18JavaScript中继承的实现方法--详解                 //this[each] = p[each];
19JavaScript中继承的实现方法--详解                 this.prototype[each] = p[each];
20JavaScript中继承的实现方法--详解            }
21JavaScript中继承的实现方法--详解        }
22JavaScript中继承的实现方法--详解    Point2D.extend();
23JavaScript中继承的实现方法--详解        //alert(Point2D.dimension);
24JavaScript中继承的实现方法--详解        alert(Point2D.prototype.dimension);
25JavaScript中继承的实现方法--详解  </script>

5、几种继承方式的比较

比较项

构造继承

原型继承

实例继承

拷贝继承

静态属性继承

N

Y

Y

Y

内置(核心)对象继承

N

部分

Y

Y

多参多重继承

Y

N

Y

N

执行效率

多继承

Y

N

N

Y

instanceof

false

true

false

false