Javascript定义类(class)的三种方法

在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称"实例")共有的属性和方法。

Javascript语言不支持"类",但是可以用一些变通的方法,模拟出"类"。

一、构造函数法
这是经典方法,也是教科书必教的方法。它用构造函数模拟"类",在其内部用this关键字指代实例对象。

1  function Cat() { 2    this.name = "大毛"; 3  }

生成实例的时候,使用new关键字。

1  var cat1 = new Cat(); 2  alert(cat1.name); // 大毛

类的属性和方法,还可以定义在构造函数的prototype对象之上。

1  Cat.prototype.makeSound = function(){ 2    alert("喵喵喵"); 3  }

关于这种方法的详细介绍,请看我写的系列文章《Javascript 面向对象编程》,这里就不多说了。它的主要缺点是,比较复杂,用到了this和prototype,编写和阅读都很费力。

二、Object.create()法
为了解决"构造函数法"的缺点,更方便地生成对象,Javascript的国际标准ECMAScript第五版(目前通行的是第三版),提出了一个新的方法Object.create()。
用这个方法,"类"就是一个对象,不是函数。

1  var Cat = { 2    name: "大毛", 3    makeSound: function(){ alert("喵喵喵"); } 4  };

然后,直接用Object.create()生成实例,不需要用到new。

1  var cat1 = Object.create(Cat); 2  alert(cat1.name); // 大毛 3  cat1.makeSound(); // 喵喵喵

目前,各大浏览器的最新版本(包括IE9)都部署了这个方法。如果遇到老式浏览器,可以用下面的代码自行部署。

1  if (!Object.create) { 2    Object.create = function (o) { 3       function F() {} 4      F.prototype = o; 5      return new F(); 6    }; 7  }

这种方法比"构造函数法"简单,但是不能实现私有属性和私有方法,实例对象之间也不能共享数据,对"类"的模拟不够全面。

三、极简主义法
荷兰程序员Gabor de Mooij提出了一种比Object.create()更好的新方法,他称这种方法为"极简主义法"(minimalist approach)。这也是我推荐的方法。
3.1 封装
这种方法不使用this和prototype,代码部署起来非常简单,这大概也是它被叫做"极简主义法"的原因。
首先,它也是用一个对象模拟"类"。在这个类里面,定义一个构造函数createNew(),用来生成实例。

1  var Cat = { 2    createNew: function(){ 3      // some code here 4    } 5  };

然后,在createNew()里面,定义一个实例对象,把这个实例对象作为返回值。

1  var Cat = { 2    createNew: function(){ 3      var cat = {}; 4      cat.name = "大毛"; 5      cat.makeSound = function(){ alert("喵喵喵"); }; 6      return cat; 7    } 8  };

使用的时候,调用createNew()方法,就可以得到实例对象。

1  var cat1 = Cat.createNew(); 2  cat1.makeSound(); // 喵喵喵

这种方法的好处是,容易理解,结构清晰优雅,符合传统的"面向对象编程"的构造,因此可以方便地部署下面的特性。
3.2 继承
让一个类继承另一个类,实现起来很方便。只要在前者的createNew()方法中,调用后者的createNew()方法即可。
先定义一个Animal类。

1  var Animal = { 2    createNew: function(){ 3      var animal = {}; 4      animal.sleep = function(){ alert("睡懒觉"); }; 5      return animal; 6    } 7  };

然后,在Cat的createNew()方法中,调用Animal的createNew()方法。

1  var Cat = { 2    createNew: function(){ 3      var cat = Animal.createNew(); 4      cat.name = "大毛"; 5      cat.makeSound = function(){ alert("喵喵喵"); }; 6      return cat; 7    } 8  };

这样得到的Cat实例,就会同时继承Cat类和Animal类。

1  var cat1 = Cat.createNew(); 2  cat1.sleep(); // 睡懒觉

3.3 私有属性和私有方法
在createNew()方法中,只要不是定义在cat对象上的方法和属性,都是私有的。

1  var Cat = { 2    createNew: function(){ 3      var cat = {}; 4      var sound = "喵喵喵"; 5      cat.makeSound = function(){ alert(sound); }; 6      return cat; 7    } 8  };

上例的内部变量sound,外部无法读取,只有通过cat的公有方法makeSound()来读取。

1  var cat1 = Cat.createNew(); 2  alert(cat1.sound); // undefined

3.4 数据共享
有时候,我们需要所有实例对象,能够读写同一项内部数据。这个时候,只要把这个内部数据,封装在类对象的里面、createNew()方法的外面即可。

1  var Cat = { 2    sound : "喵喵喵", 3    createNew: function(){ 4      var cat = {}; 5      cat.makeSound = function(){ alert(Cat.sound); }; 6      cat.changeSound = function(x){ Cat.sound = x; }; 7      return cat; 8    } 9  };

然后,生成两个实例对象:

1  var cat1 = Cat.createNew(); 2  var cat2 = Cat.createNew(); 3  cat1.makeSound(); // 喵喵喵

这时,如果有一个实例对象,修改了共享的数据,另一个实例对象也会受到影响。

1  cat2.changeSound("啦啦啦"); 2  cat1.makeSound(); // 啦啦啦
点赞
收藏

评论区

加载中...

相关推荐

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java中的类与对象(1)

    首先理解一下类和对象的关系,可以说:类是对象的抽象,对象是类的实例。类一个类中,通常上包含了属性和功能。属性通常用变量表达,功能通常上用函数表达。编写一个类class类名{//属性,用变量表达//功能,用函数表达}对象实例化对象的方法及含义:类名 对象名 new 

JS 对象数组Array 根据对象object key的值排序sort,很风骚哦

有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak

Java 类及类的构造方法

类类是一个模子,确定对象将会拥有的特性(属性)和行为(方法)。类的特点  类时对象的类型  具有相同属性和方法的一组对象的集合构造方法作用就是对类进行初始化。如果你没有定议任何构造方法的形式,Java会为你取一个不带任何参数的构造函数,那么你产生类的对像时只能用不带参数的方法,如:classa{}//没

JavaScript中的类定义和继承实现

ES5中因为没有class关键字,所以创建类的方式是通过构造函数来定义的。我将一步步的用代码演示如何慢慢用原生的语法实现JS的类的定义和继承。希望大家喜欢。废话不多说,我们来看原生JavaScript定义类的方法。1\.最简单的类//类的构造函数functionPerson(){this.nam