`

Javascript面向对象 --3 -- 【继承】

阅读更多

 最佳实践:

(1) 定义基类,在基类构造函数中定义属性和私有方法,在基类的prototype中连接方法(function)

(2) 定义一个空对象F,空对象的prototype属性指向基类的prototype属性

(3) 定义子类,在子类的构造函数中调用基类的call方法

(4) 设置子类的prototype属性为(2)F的示例(new 一个 F)

具体,建下面 第3部分.

 

1. javascript继承,在子类的构造函数的第一行执行 基类的call方法.

 

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
  }
  
  //定义一个子类
  function Cat(name,color)
  {
     Animal.call(this);//相当于调用基类的构造函数
     this.name = name;
     this.color = color;
  } 
  
  var aCat = new Cat('Tom','black');
  console.log(aCat);

 上面console.log(aCat);代码的输出为:

 

Cat {species: "动物", name: "Tom", color: "black"}

 

从这个输出可见这里子类正确的获得了基类的species属性.

 

 

这样做有两个问题:

(1)  基类的prototype中的属性和方法将不被继承.

(2)  基类的静态属性和方法不被继承

代码如下:

 

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
  }
  
  Animal.prototype.show = function() { alert('This is An Animal.');}; //定义基类一个普通方法
  
  Animal.legCount=4; //定义动物有4条腿,类的静态属性
  Animal.TestStaticFunction = function() {alert('TestStaticFunction.');};//基类,静态方法
  
  //定义一个子类
  function Cat(name,color)
  {
     Animal.call(this);//相当于调用基类的构造函数,将基类的属性继承过来,但仅限于在基类的构造函数中定义的属性
     this.name = name;
     this.color = color;
  } 
  
  var anAnimal = new Animal();
  var aCat = new Cat('Tom','black');
  
  console.log(Animal.legCount); //4,基类静态属性,使用类访问,正常
  //console.legCount(anAnimal.legCount);//报错,静态属性只能通过类访问
  Animal.TestStaticFunction(); //基类静态方法,使用类访问,正常
  //anAnimal.TestStaticFunction(); //报错,静态属性只能通过类访问
  
  console.log(aCat); 
  console.log(aCat.legCount);//undefined,静态属性,只能通过类访问(Java中能通过实例访问静态属性)
  console.log(Cat.legCount); //undefined,静态属性,不能继承
  //Cat.TestStaticFunction(); //报错,Cat没有从基类继承 静态方法 TestStaticFunction()
  
  anAnimal.show(); //基类prototype中方法,正常访问
  //aCat.show();   //报错,没有show()方法
 

 

上面的问题(2)解决方法 参见 

http://jackyin5918.iteye.com/blog/1973113

(非构造函数继承_解决Javascript不能继承基类静态方法和静态变量)

 

下面解决问题(1)  基类的prototype中的属性和方法将不被继承

 

2. 解决 基类的prototype中的属性和方法将不被继承

使用下面代码:

 

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
  }
  
  Animal.prototype.show = function() { alert('This is An Animal. name=' + this.name);}; //定义基类一个普通方法
  
  Animal.legCount=4; //定义动物有4条腿,类的静态属性
  Animal.TestStaticFunction = function() {alert('TestStaticFunction.');};//基类,静态方法
  
  //定义一个子类
  function Cat(name,color)
  {
     Animal.call(this);//相当于调用基类的构造函数,将基类的属性继承过来,但仅限于在基类的构造函数中定义的属性
     this.name = name;
     this.color = color;
  } 
  
  Cat.prototype = new Animal();     //基类的prototype指向 一个新的Animal()对象,
  //通过prototype链(原型链)连接到基类的prototype上,从而实现继承基类的prototype
  Cat.prototype.constructor = Cat; //因为每个类的prototype对象都有个constructor属性,指向类自己,
  //这里需要Cat.prototype其实是Animal,而Animal的constructor是指向Animal的,
  //造成了Cat的constructor指向了Animal,产生混乱,需要修正过来

  var anAnimal = new Animal();
  var aCat = new Cat('Tom','black');
  
  console.log(aCat); 
  anAnimal.show(); //基类prototype中方法,正常访问,(但基类中this.name未定义)
  aCat.show();     //正常,通过prototype方式继承了基类prototype中的方法
 上面代码,解决了基类prototype中方法和属性不能继承问题,但是也产生了一个新问题,

 

就是在定义子类的时候 调用

Cat.prototype = new Animal();     //基类的prototype指向 一个新的Animal()对象,

这一句时,生成了一个基类对象Animal(),造成了内存浪费,应该避免.

 

3. 优化,解决内存浪费问题

使用下面代码,基本上可以完美实现继承:

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
  }
  
  Animal.prototype.show = function() { alert('This is An Animal. name=' + this.name);}; //定义基类一个普通方法
  
  Animal.legCount=4; //定义动物有4条腿,类的静态属性
  Animal.TestStaticFunction = function() {alert('TestStaticFunction.');};//基类,静态方法
  
  //定义一个子类
  function Cat(name,color)
  {
     Animal.call(this);//相当于调用基类的构造函数,将基类的属性继承过来,但仅限于在基类的构造函数中定义的属性
     this.name = name;
     this.color = color;
  } 
  
  var EmptyObject = function(){}; //
 EmptyObject.prototype = Animal.prototype;
 Cat.prototype = new EmptyObject();  //修改Cat的prototype不会影响到基类的prototype
  Cat.prototype.constructor = Cat;    //因为每个类的prototype对象都有个constructor属性,指向类自己,
  //这里需要Cat.prototype其实是Animal,而Animal的constructor是指向Animal的,
  //造成了Cat的constructor指向了Animal,产生混乱,需要修正过来

  var anAnimal = new Animal();
  var aCat = new Cat('Tom','black');
  
  console.log(aCat); 
  anAnimal.show(); //基类prototype中方法,正常访问,(但基类中this.name未定义)
  aCat.show();     //正常,通过prototype方式继承了基类prototype中的方法

 

4. 实现类继承的函数:

    

function extend(Child, Parent) {

    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.uber = Parent.prototype;
  }

 5. 另一种实现继承的方式--拷贝属性方式

function extend2(Child, Parent)
 {
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
      c[i] = p[i];
      }
    c.uber = p;
  }

 

 

这部分主要学习了下面两篇文章:

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html

还有参考了这个:

http://msdn.microsoft.com/zh-cn/magazine/cc163419.aspx#S4

 

分享到:
评论

相关推荐

    JavaScript面向对象编程--继承.mht

    JavaScript面向对象编程--继承.mht,JavaScript面向对象编程--继承.mht,JavaScript面向对象编程--继承.mht,JavaScript面向对象编程--继承.mht

    JavaScript面向对象-动力节点共7页.pdf.z

    JavaScript面向对象是编程语言JavaScript中的核心概念之一,它在实际开发中扮演着至关重要的角色。JavaScript,虽然最初设计为一种轻量级的脚本语言,但随着其发展,逐渐引入了面向对象的特性,使得它能够支持更复杂...

    Javascript面向对象编程.

    在提供的资源中,《代码之美》PDF文件可能包含了关于编程实践和代码风格的指导,而《Javascript面向对象编程》PPT可能更具体地阐述了JavaScript OOP的细节和示例。学习这些材料将有助于深入理解JavaScript的面向对象...

    面向对象JavaScript精要(英文原版pdf)

    ### 面向对象JavaScript精要 #### 一、书籍概览 本书《面向对象JavaScript精要》由Nicholas C. Zakas编写,是面向对象编程领域中的权威指南之一,尤其针对JavaScript这门语言。作者深入浅出地介绍了面向对象编程的...

    JavaScript面向对象编程指南

    《JavaScript面向对象编程指南》内容包括:JavaScript作为一门浏览器语言的核心思想;面向对象编程的基础知识及其在JavaScript中的运用;数据类型、操作符以及流程控制语句;函数、闭包、对象和原型等概念,以代码...

    JavaScript面向对象编程指南.pdf

    JavaScript作为一门浏览器语言的核心思想;面向对象编程的基础知识及其在... 《JavaScript面向对象编程指南》着重介绍JavaScript在面向对象方面的特性,展示如何构建强健的、可维护的、功能强大的应用程序及程序库

    JAVASCRIPT 面向对象编程精要

    本文介绍了JavaScript面向对象编程的基本概念和技术细节,包括变量和对象的基础用法、函数的作用以及如何通过封装和继承来构建复杂的对象层次结构。JavaScript的独特之处在于它的灵活性和动态性,这使得它成为了一种...

    浅谈JavaScript面向对象--继承

    继承是面向对象编程(OOP)的核心概念之一,在JavaScript中实现继承有多种...以上内容详细解释了JavaScript面向对象继承的概念和实现步骤,相信对于正在学习或准备深入学习JavaScript的开发者来说具有重要的参考价值。

    JavaScript面向对象编程指南(第2版).rar

    JavaScript是一种广泛...通过深入学习这本《JavaScript面向对象编程指南(第2版)》,开发者不仅能掌握JavaScript的面向对象编程基础,还能了解到实际项目中如何有效地运用这些知识,提升编程技巧和解决问题的能力。

    javascript面向对象编程(中文).pdf

    ### JavaScript面向对象编程知识点概述 #### 一、现代JavaScript编程概览 - **JavaScript的演进**:自诞生以来,JavaScript经历了从一个简单的脚本语言到现今被广泛应用于构建复杂应用的强大编程语言的过程。它的...

    JavaScript面向对象编程指南 pdf

    下面将详细探讨JavaScript面向对象编程的基本原理、特性以及实际应用。 1. **类与对象** - 在JavaScript中,对象是键值对的集合,可以通过字面量语法或构造函数创建。例如: ```javascript const person = { ...

    JavaScript面向对象继承详解

    本文将深入探讨JavaScript中的面向对象继承,这是理解JavaScript OOP的关键部分。 面向对象继承是实现代码复用和模块化的重要机制。在JavaScript中,继承主要通过原型链(Prototype Chain)实现。每个JavaScript...

    javascript基础-->中级-->高级-->面向对象

    四、JavaScript面向对象 1. 构造函数与new操作符:构造函数用于创建特定类型的对象,new操作符则是调用构造函数的手段。 2. prototype与__proto__:两者都与原型链有关,prototype是构造函数的属性,__proto__是...

    JavaScript面向对象精要(英文版)

    ### JavaScript面向对象精要 #### 一、概述 《JavaScript面向对象精要》是一本深入讲解JavaScript面向对象编程原理的专业书籍。本书由知名的前端开发者Nicholas C. Zakas撰写,全面介绍了JavaScript作为一种动态...

    面向对象JavaScript开发

    JavaScript,作为一种广泛应用...JavaScript 面向对象程序设计——继承与多态.pdf 和 JavaScript 面向对象程序设计——封装.pdf 这两个文档可能深入探讨了这些主题,帮助读者深入理解并掌握JavaScript的面向对象开发。

    学习javascript面向对象 javascript实现继承的方式

    以上六种继承方式在JavaScript面向对象编程中各有用途,开发者可以根据具体需求选择最适合的继承方式。需要注意的是,虽然继承可以使代码复用性更高,但过度的继承层次和复杂的继承关系可能会导致代码难以理解与维护...

    javascript 经典面向对象设计

    ### JavaScript经典面向对象设计 #### 标题与描述解析 标题“JavaScript经典面向对象设计”指出了本书的主要内容是关于如何使用面向对象编程(OOP)原则和技术来编写高质量、可扩展且可重用的JavaScript应用程序及...

    javascript面向对象框架

    "javascript面向对象框架"这一主题涵盖了JavaScript中实现面向对象编程的框架,特别是Prototype和MooTools这两个优秀的库。 Prototype是JavaScript的一个开源库,它扩展了JavaScript的基本对象和函数,提供了强大的...

    javascript面向对象编程

    面向对象编程的基础知识及其在JavaScript中的运用;数据类型、操作符以及流程控制语句;函数、闭包、对象和原型等概念,以代码重用为目的的继承模式;BOM、DOM、浏览器事件、AJAX和JSON;如何实现JavaScript中缺失的...

Global site tag (gtag.js) - Google Analytics