JavaScript面向对象编程[转]

简介:

命名空间

命名空间是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。 在JavaScript中,命名空间只是另一个包含方法,属性,对象的对象。

需要认识到非常重要的一点,与其他面向对象编程语言中的普通对象和命名空间相比,它们在语言层面上没有区别。

创造的JavaScript命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。

我们来创建一个全局变量叫做 MYAPP

1
2
<code class = " language-js" ><span class = "token comment" > // 全局命名空间
<span class = "token keyword" > var  MYAPP <span class = "token operator" >= MYAPP <span class = "token operator" >|| <span class = "token punctuation" >{<span class = "token punctuation" >}<span class = "token punctuation" >;</span></span></span></span></span></span></span></code>
 

在上面的代码示例中,我们首先检查MYAPP是否已经被定义(是否在同一文件中或在另一文件)。如果是的话,那么使用现有的MYAPP全局对象,否则,创建一个名为MYAPP的空对象用来封装方法,函数,变量和对象。

我们也可以创建子命名空间:

1
2
<code class = " language-js" ><span class = "token comment" > // 子命名空间
MYAPP<span class = "token punctuation" >.event <span class = "token operator" >= <span class = "token punctuation" >{<span class = "token punctuation" >}<span class = "token punctuation" >;</span></span></span></span></span></span></code>
 

下面是用于创建命名空间和添加变量,函数和方法的代码写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<code class = " language-js" ><span class = "token comment" > // 给普通方法和属性创建一个叫做MYAPP.commonMethod的容器
MYAPP<span class = "token punctuation" >.commonMethod <span class = "token operator" >= <span class = "token punctuation" >{
   regExForName<span class = "token punctuation" >: <span class = "token string" > "" <span class = "token punctuation" >,<span class = "token comment" > // 定义名字的正则验证
   regExForPhone<span class = "token punctuation" >: <span class = "token string" > "" <span class = "token punctuation" >,<span class = "token comment" > // 定义电话的正则验证
   validateName<span class = "token punctuation" >: <span class = "token keyword" > function <span class = "token punctuation" >(name<span class = "token punctuation" >)<span class = "token punctuation" >{
    <span class = "token comment" > // 对名字name做些操作,你可以通过使用“this.regExForname”
    <span class = "token comment" > // 访问regExForName变量
   <span class = "token punctuation" >}<span class = "token punctuation" >,
  
   validatePhoneNo<span class = "token punctuation" >: <span class = "token keyword" > function <span class = "token punctuation" >(phoneNo<span class = "token punctuation" >)<span class = "token punctuation" >{
    <span class = "token comment" > // 对电话号码做操作
   <span class = "token punctuation" >}
<span class = "token punctuation" >}
<span class = "token comment" >
// 对象和方法一起申明
MYAPP<span class = "token punctuation" >.event <span class = "token operator" >= <span class = "token punctuation" >{
     addListener<span class = "token punctuation" >: <span class = "token keyword" > function <span class = "token punctuation" >(el<span class = "token punctuation" >, type<span class = "token punctuation" >, fn<span class = "token punctuation" >) <span class = "token punctuation" >{
    <span class = "token comment" > //  代码
     <span class = "token punctuation" >}<span class = "token punctuation" >,
    removeListener<span class = "token punctuation" >: <span class = "token keyword" > function <span class = "token punctuation" >(el<span class = "token punctuation" >, type<span class = "token punctuation" >, fn<span class = "token punctuation" >) <span class = "token punctuation" >{
    <span class = "token comment" > // 代码
    <span class = "token punctuation" >}<span class = "token punctuation" >,
    getEvent<span class = "token punctuation" >: <span class = "token keyword" > function <span class = "token punctuation" >(e<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token comment" > // 代码
    <span class = "token punctuation" >}
   
   <span class = "token comment" > // 还可以添加其他的属性和方法
<span class = "token punctuation" >}
<span class = "token comment" >
//使用addListner方法的写法:
MYAPP<span class = "token punctuation" >.event<span class = "token punctuation" >.<span class = "token function" >addListener<span class = "token punctuation" >(<span class = "token string" > "yourel" <span class = "token punctuation" >, <span class = "token string" > "type" <span class = "token punctuation" >, callback<span class = "token punctuation" >)<span class = "token punctuation" >;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

标准内置对象

JavaScript有包括在其核心的几个对象,例如,Math,Object,Array和String对象。下面的例子演示了如何使用Math对象使用其随机()方法来获得一个随机数。

1
<code class = " language-js" >console<span class = "token punctuation" >.<span class = "token function" >log<span class = "token punctuation" >(Math<span class = "token punctuation" >.<span class = "token function" >random<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >)<span class = "token punctuation" >;</span></span></span></span></span></span></span></span></span></code>
 
注意:T这里和接下来的例子都假设名为  console.log 的方法全局有定义。 console.log 实际上不是 JavaScript 自带的。

查看 JavaScript 参考:全局对象 了解 JavaScript 内置对象的列表。

JavaScript 中的每个对象都是 Object 对象的实例且继承它所有的属性和方法。

自定义对象

JavaScript是一种基于原型的语言,它没类的声明语句,比如C+ +或Java中用的。这有时会对习惯使用有类申明语句语言的程序员产生困扰。相反,JavaScript可用方法作类。定义一个类跟定义一个函数一样简单。在下面的例子中,我们定义了一个新类Person。

1
2
3
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(<span class = "token punctuation" >) <span class = "token punctuation" >{ <span class = "token punctuation" >} <span class = "token comment" >
// 或
<span class = "token keyword" > var  Person <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >{ <span class = "token punctuation" >}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

对象(类的实例)

我们使用 new obj 创建对象 obj 的新实例, 将结果(obj 类型)赋值给一个变量方便稍后调用。

在下面的示例中,我们定义了一个名为Person的类,然后我们创建了两个Person的实例(person1 and person2).

1
2
3
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(<span class = "token punctuation" >) <span class = "token punctuation" >{ <span class = "token punctuation" >}
<span class = "token keyword" > var  person1 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token keyword" > var  person2 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 
有两种为对象创建实例,请参考  Object.create 。

构造器

在实例化时构造器被调用 (也就是对象实例被创建时)。构造器是对象中的一个方法。 在JavaScript,中函数就可以作为构造器使用,因此不需要特别地定义一个构造器方法. 每个声明的函数都可以在实例化后被调用执行

构造器常用于给对象的属性赋值或者为调用函数做准备。 在本文的后面描述了类中方法既可以在定义时添加,也可以在使用前添加。

在下面的示例中, Person类实例化时构造器调用一个 alert函数。

1
2
3
4
5
6
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > 'Person instantiated' <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}
 
<span class = "token keyword" > var  person1 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token keyword" > var  person2 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

属性 (对象属性)

属性就是 类中包含的变量;每一个对象实例有若干个属性. 为了正确的继承,属性应该被定义在类的原型属性 (函数)中。

可以使用 关键字 this调用类中的属性, this是对当前对象的引用。 从外部存取(读/写)其属性的语法是: InstanceName.Property; 这与C++,Java或者许多其他语言中的语法是一样的 (在类中语法 this.Property 常用于set和get属性值)

在下面的示例中,我们为定义Person类定义了一个属性 firstName 并在实例化时赋初值。

1
2
3
4
5
6
7
8
9
10
11
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(firstName<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token keyword" > this <span class = "token punctuation" >.firstName <span class = "token operator" >= firstName<span class = "token punctuation" >;
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > 'Person instantiated' <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}
 
<span class = "token keyword" > var  person1 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token string" > 'Alice' <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token keyword" > var  person2 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token string" > 'Bob' <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token comment" >
// Show the firstName properties of the objects
<span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > 'person1 is '  <span class = "token operator" >+ person1<span class = "token punctuation" >.firstName<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // alerts "person1 is Alice"
<span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > 'person2 is '  <span class = "token operator" >+ person2<span class = "token punctuation" >.firstName<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // alerts "person2 is Bob"</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

方法

方法与属性很相似, 不同的是:一个是函数,另一个可以被定义为函数。 调用方法很像存取一个属性,  不同的是add () 在方法名后面很可能带着参数. 为定义一个方法, 需要将一个函数赋值给类的 prototype 属性; 这个赋值给函数的名称就是用来给对象在外部调用它使用的。

在下面的示例中,我们给Person类定义了方法 sayHello(),并调用了它.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(firstName<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token keyword" > this <span class = "token punctuation" >.firstName <span class = "token operator" >= firstName<span class = "token punctuation" >;
<span class = "token punctuation" >}
 
Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >.sayHello <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > "Hello, I'm "  <span class = "token operator" >+ <span class = "token keyword" > this <span class = "token punctuation" >.firstName<span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
 
<span class = "token keyword" > var  person1 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token string" > "Alice" <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token keyword" > var  person2 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token string" > "Bob" <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token comment" >
// call the Person sayHello method.
person1<span class = "token punctuation" >.<span class = "token function" >sayHello<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // alerts "Hello, I'm Alice"
person2<span class = "token punctuation" >.<span class = "token function" >sayHello<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // alerts "Hello, I'm Bob"</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

在JavaScript中方法通常是一个绑定到对象中的普通函数, 这意味着方法可以在其所在context之外被调用。 思考下面示例中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(firstName<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token keyword" > this <span class = "token punctuation" >.firstName <span class = "token operator" >= firstName<span class = "token punctuation" >;
<span class = "token punctuation" >}
 
Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >.sayHello <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > "Hello, I'm "  <span class = "token operator" >+ <span class = "token keyword" > this <span class = "token punctuation" >.firstName<span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
 
<span class = "token keyword" > var  person1 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token string" > "Alice" <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token keyword" > var  person2 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Person<span class = "token punctuation" >(<span class = "token string" > "Bob" <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token keyword" > var  helloFunction <span class = "token operator" >= person1<span class = "token punctuation" >.sayHello<span class = "token punctuation" >;
 
person1<span class = "token punctuation" >.<span class = "token function" >sayHello<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;                                <span class = "token comment" > // alerts "Hello, I'm Alice"
person2<span class = "token punctuation" >.<span class = "token function" >sayHello<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;                                <span class = "token comment" > // alerts "Hello, I'm Bob"
<span class = "token function" >helloFunction<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;                                   <span class = "token comment" > // alerts "Hello, I'm undefined" (or fails
                                                    <span class = "token comment" > // with a TypeError in strict mode)
<span class = "token function" >alert<span class = "token punctuation" >(helloFunction <span class = "token operator" >=== person1<span class = "token punctuation" >.sayHello<span class = "token punctuation" >)<span class = "token punctuation" >;         <span class = "token comment" > // alerts true
<span class = "token function" >alert<span class = "token punctuation" >(helloFunction <span class = "token operator" >=== Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >.sayHello<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // alerts true
helloFunction<span class = "token punctuation" >.<span class = "token function" >call<span class = "token punctuation" >(person1<span class = "token punctuation" >)<span class = "token punctuation" >;                       <span class = "token comment" > // alerts "Hello, I'm Alice"</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

如上例所示, 所有指向sayHello函数的引用 ,包括 person1Person.prototype, 和 helloFunction 等, 均引用了相同的函数.

在调用函数的过程中,this的值取决于我们怎么样调用函数.  在通常情况下,我们通过一个表达式person1.sayHello()来调用函数:即从一个对象的属性中得到所调用的函数。此时this被设置为我们取得函数的对象(即person1)。这就是为什么person1.sayHello() 使用了姓名“Alice”而person2.sayHello()使用了姓名“bob”的原因。 

然而我们使用不同的调用方法时, this的值也就不同了。当从变量 helloFunction()中调用的时候, this就被设置成了全局对象 (在浏览器中即window)。由于该对象 (非常可能地) 没有firstName 属性, 我们得到的结果便是"Hello, I'm undefined". (这是松散模式下的结果, 在 严格模式中,结果将不同(此时会产生一个error)。 但是为了避免混淆,我们在这里不涉及细节) 。另外,我们可以像上例末尾那样,使用Function#call (或者Function#apply)显式的设置this的值。

更多有关信息请参考  Function#call and  Function#apply

继承

创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。 创建的专门版本的类通常叫做子类,另外的类通常叫做父类。 在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。在现代浏览器中你可以使用 Object.create 实现继承.

JavaScript 并不检测子类的 prototype.constructor (见 Object.prototype), 所以我们必须手动申明它.

在下面的例子中, 我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了 sayGoodBye() 方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<code class = " language-js" ><span class = "token comment" > // 定义Person构造器
<span class = "token keyword" > function  <span class = "token function" >Person<span class = "token punctuation" >(firstName<span class = "token punctuation" >) <span class = "token punctuation" >{
   <span class = "token keyword" > this <span class = "token punctuation" >.firstName <span class = "token operator" >= firstName<span class = "token punctuation" >;
<span class = "token punctuation" >}
<span class = "token comment" >
// 在Person.prototype中加入方法
Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >.walk <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > "I am walking!" <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >.sayHello <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > "Hello, I'm "  <span class = "token operator" >+ <span class = "token keyword" > this <span class = "token punctuation" >.firstName<span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
<span class = "token comment" >
// 定义Student构造器
<span class = "token keyword" > function  <span class = "token function" >Student<span class = "token punctuation" >(firstName<span class = "token punctuation" >, subject<span class = "token punctuation" >) <span class = "token punctuation" >{
  <span class = "token comment" > // 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
   Person<span class = "token punctuation" >.<span class = "token function" >call<span class = "token punctuation" >(<span class = "token keyword" > this <span class = "token punctuation" >, firstName<span class = "token punctuation" >)<span class = "token punctuation" >;
 
  <span class = "token comment" > // 初始化Student类特有属性
   <span class = "token keyword" > this <span class = "token punctuation" >.subject <span class = "token operator" >= subject<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
<span class = "token comment" >
// 建立一个由Person.prototype继承而来的Student.prototype对象.
<span class = "token comment" > // 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
<span class = "token comment" > // 这样做的错误之处有很多, 最重要的一点是我们在实例化时
<span class = "token comment" > // 不能赋予Person类任何的FirstName参数
<span class = "token comment" > // 调用Person的正确位置如下,我们从Student中来调用它
Student<span class = "token punctuation" >.prototype <span class = "token operator" >= Object<span class = "token punctuation" >.<span class = "token function" >create<span class = "token punctuation" >(Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // See note below
<span class = "token comment" >
// 设置"constructor" 属性指向Student
Student<span class = "token punctuation" >.prototype<span class = "token punctuation" >.constructor <span class = "token operator" >= Student<span class = "token punctuation" >;
<span class = "token comment" >
// 更换"sayHello" 方法
Student<span class = "token punctuation" >.prototype<span class = "token punctuation" >.sayHello <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > "Hello, I'm "  <span class = "token operator" >+ <span class = "token keyword" > this <span class = "token punctuation" >.firstName <span class = "token operator" >+ <span class = "token string" > ". I'm studying "  <span class = "token operator" >+ <span class = "token keyword" > this <span class = "token punctuation" >.subject <span class = "token operator" >+ <span class = "token string" > "." <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
<span class = "token comment" >
// 加入"sayGoodBye" 方法
Student<span class = "token punctuation" >.prototype<span class = "token punctuation" >.sayGoodBye <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >{
   <span class = "token function" >alert<span class = "token punctuation" >(<span class = "token string" > "Goodbye!" <span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}<span class = "token punctuation" >;
<span class = "token comment" >
// 测试实例:
<span class = "token keyword" > var  student1 <span class = "token operator" >= <span class = "token keyword" > new  <span class = "token class-name" >Student<span class = "token punctuation" >(<span class = "token string" > "Janet" <span class = "token punctuation" >, <span class = "token string" > "Applied Physics" <span class = "token punctuation" >)<span class = "token punctuation" >;
student1<span class = "token punctuation" >.<span class = "token function" >sayHello<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;  <span class = "token comment" > // "Hello, I'm Janet. I'm studying Applied Physics."
student1<span class = "token punctuation" >.<span class = "token function" >walk<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;      <span class = "token comment" > // "I am walking!"
student1<span class = "token punctuation" >.<span class = "token function" >sayGoodBye<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // "Goodbye!"
<span class = "token comment" >
// Check that instanceof works correctly
<span class = "token function" >alert<span class = "token punctuation" >(student1 <span class = "token keyword" > instanceof  <span class = "token class-name" >Person<span class = "token punctuation" >)<span class = "token punctuation" >; <span class = "token comment" > // true
<span class = "token function" >alert<span class = "token punctuation" >(student1 <span class = "token keyword" > instanceof  <span class = "token class-name" >Student<span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // true</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

对于“Student.prototype = Object.create(Person.prototype);”这一行,在不支持 Object.create方法的老JavaScript引擎中,可以使用一个"polyfill"(又名"shim",查看文章链接),或者使用一个function来获得相同的返回值,就像下面:

1
2
3
4
5
6
7
8
<code class = " language-js" ><span class = "token keyword" > function  <span class = "token function" >createObject<span class = "token punctuation" >(proto<span class = "token punctuation" >) <span class = "token punctuation" >{
     <span class = "token keyword" > function  <span class = "token function" >ctor<span class = "token punctuation" >(<span class = "token punctuation" >) <span class = "token punctuation" >{ <span class = "token punctuation" >}
     ctor<span class = "token punctuation" >.prototype <span class = "token operator" >= proto<span class = "token punctuation" >;
     <span class = "token keyword" > return  <span class = "token keyword" > new  <span class = "token class-name" >ctor<span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >;
<span class = "token punctuation" >}
<span class = "token comment" >
// Usage:
Student<span class = "token punctuation" >.prototype <span class = "token operator" >= <span class = "token function" >createObject<span class = "token punctuation" >(Person<span class = "token punctuation" >.prototype<span class = "token punctuation" >)<span class = "token punctuation" >;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 
更多相关信息请参考  Object.create,连接中还有一个老JavaScript引擎的兼容方案(shim)。

封装

在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。

抽象

抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承(具体化)或组合来实现。
JavaScript通过继承实现具体化,通过让类的实例是其他对象的属性值来实现组合。

JavaScript Function 类继承自Object类(这是典型的具体化) 。Function.prototype的属性是一个Object实例(这是典型的组合)。

1
2
3
<code class = " language-js" ><span class = "token keyword" > var  foo <span class = "token operator" >= <span class = "token keyword" > function <span class = "token punctuation" >(<span class = "token punctuation" >)<span class = "token punctuation" >{<span class = "token punctuation" >}<span class = "token punctuation" >;
<span class = "token function" >alert<span class = "token punctuation" >( <span class = "token string" > 'foo is a Function: '  <span class = "token operator" >+ <span class = "token punctuation" >(foo <span class = "token keyword" > instanceof  <span class = "token class-name" >Function<span class = "token punctuation" >) <span class = "token punctuation" >)<span class = "token punctuation" >;                 <span class = "token comment" > // alerts "foo is a Function: true"
<span class = "token function" >alert<span class = "token punctuation" >( <span class = "token string" > 'foo.prototype is an Object: '  <span class = "token operator" >+ <span class = "token punctuation" >(foo<span class = "token punctuation" >.prototype <span class = "token keyword" > instanceof  <span class = "token class-name" >Object<span class = "token punctuation" >) <span class = "token punctuation" >)<span class = "token punctuation" >;<span class = "token comment" > // alerts "foo.prototype is an Object: true"</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
 

多态

就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。

注意

本文中所展示的面向对象编程技术不是唯一的实现方式,在JavaScript中面向对象的实现是非常灵活的。

同样的,文中展示的技术没有使用任何语言hacks,它们也没有模仿其他语言的对象理论实现。

JavaScript中还有其他一些更加先进的面向对象技术,但这些都超出了本文的介绍范围。

 

文章出处:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!




















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/4414045.html ,如需转载请自行联系原作者

相关文章
|
存储 前端开发 JavaScript
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
|
前端开发 JavaScript 开发者
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
|
JavaScript 前端开发 Java
深入JS面向对象(原型-继承)(三)
深入JS面向对象(原型-继承)
90 0
|
JavaScript 前端开发 Java
深入JS面向对象(原型-继承)(一)
深入JS面向对象(原型-继承)
120 0
|
11月前
|
JavaScript 前端开发 Java
JavaScript中的面向对象编程(OOP) - 终极指南
本文介绍了 JavaScript 的面向对象编程 (OOP) 概念,包括继承、多态、封装和抽象等关键要素,并通过代码示例帮助开发者理解和应用 OOP 思维。
181 5
|
12月前
|
JavaScript 前端开发 Java
js面向对象编程|24
js面向对象编程|24
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
278 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
JavaScript 前端开发 Java
使用JavaScript进行面向对象编程的指南
使用JavaScript进行面向对象编程的指南
82 4
|
前端开发 JavaScript 安全
TypeScript作为一种静态类型的JavaScript超集,其强大的类型系统和面向对象编程特性为微前端架构的实现提供了有力的支持
【6月更文挑战第11天】微前端架构借助TypeScript提升开发效率和代码可靠性。 TypeScript提供类型安全,防止微前端间通信出错;智能提示和自动补全加速跨代码库开发;重构支持简化代码更新。通过定义公共接口确保一致性,用TypeScript编写微前端以保证质量。集成到构建流程确保顺利构建打包。在微前端场景中,TypeScript是强有力的语言选择。
96 2
|
前端开发 JavaScript
前端 JS 经典:Class 面向对象
前端 JS 经典:Class 面向对象
83 1