js基础进阶2-2 面向对象(类与对象的创建与使用)

前言:上一篇文章js基础进阶2-1 面向对象(类与对象介绍)对类与对象的一些基本概念进行了描述,接下来进入类的创建与使用。
由于js中并没有明确定义类,实现类的方式有很多种,本篇文章仅选取几个典型的做法进行说明。如果想要了解更多实现方式,请移步w3cschool,本篇文章亦是由此参考而作。

原始的方式

var oCar = new Object;
oCar.color = "blue";
oCar.doors = 4;
oCar.mpg = 25;
oCar.showColor = function() {
  alert(this.color);
};

缺点:这样的方式缺点很明显,无法创建多个类似的实例,实际上这样的方式并没有构成一个类,这只是一个单体对象。

构造函数方式

function Car(sColor,iDoors,iMpg) {
  this.color = sColor;
  this.doors = iDoors;
  this.mpg = iMpg;
  this.showColor = function() {
    alert(this.color);
  };
}

var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);

优点:通过构造函数创建了一个类,使用new关键字进行实例化,而且可以给函数传递配置参数。

缺点:其实笔者最开始学习js面向对象的时候,一直是这样的写法,但是这样的写法有一个很大的弊端,那就是构造函数会重复生成函数,这是对内存不必要的浪费。

原型方式

function Car() {
}

Car.prototype.color = "blue";
Car.prototype.doors = 4;
Car.prototype.mpg = 25;
Car.prototype.showColor = function() {
  alert(this.color);
};

var oCar1 = new Car();
var oCar2 = new Car();

优点:原型链prototype上的属性或方法只会被创建一次,故而没有了构造函数的缺点。
缺点:不能通过给构造函数传递参数来初始化属性的值

混合的构造函数/原型方式

function Car(sColor,iDoors,iMpg) {
  this.color = sColor;
  this.doors = iDoors;
  this.mpg = iMpg;
  this.drivers = new Array("Mike","John");
}

Car.prototype.showColor = function() {
  alert(this.color);
};

var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);

oCar1.drivers.push("Bill");

alert(oCar1.drivers);   //输出 "Mike,John,Bill"
alert(oCar2.drivers);   //输出 "Mike,John"

优点:将原型方式和构造函数方式进行结合,解决了两者的缺点。这种方式是目前比较主流的创建类的方式。

缺点:方法在视觉上被暴露在类定义的外面。对于习惯使用其他语言的开发者来说,使用混合的构造函数/原型方式感觉不那么和谐。毕竟,定义类时,大多数面向对象语言都对属性和方法进行了视觉上的封装。请看下面的 Java 类:

class Car {
  public String color = "blue";
  public int doors = 4;
  public int mpg = 25;

  public Car(String color, int doors, int mpg) {
    this.color = color;
    this.doors = doors;
    this.mpg = mpg;
  }

  public void showColor() {
    System.out.println(color);
  }
}

动态原型方法

function Car(sColor,iDoors,iMpg) {
  this.color = sColor;
  this.doors = iDoors;
  this.mpg = iMpg;
  this.drivers = new Array("Mike","John");

  if (typeof Car._initialized == "undefined") {
    Car.prototype.showColor = function() {
      alert(this.color);
    };

    Car._initialized = true;
  }
}

优点:该方法使用标志(_initialized)来判断是否已给原型赋予了任何方法。该方法只创建并赋值一次。这样就解决了构造函数方式中的缺点,而且也将方法封装到了类的内部。

对象的销毁

CMAScript 拥有无用存储单元收集程序(garbage collection routine),意味着不必专门销毁对象来释放内存。当再没有对对象的引用时,称该对象被废除(dereference)了。运行无用存储单元收集程序时,所有废除的对象都被销毁。每当函数执行完它的代码,无用存储单元收集程序都会运行,释放所有的局部变量,还有在一些其他不可预知的情况下,无用存储单元收集程序也会运行。

把对象的所有引用都设置为 null,可以强制性地废除对象。例如:

var oObject = new Object;
// do something with the object here
oObject = null;

当变量 oObject 设置为 null 后,对第一个创建的对象的引用就不存在了。这意味着下次运行无用存储单元收集程序时,该对象将被销毁。
每用完一个对象后,就将其废除,来释放内存,这是个好习惯。这样还确保不再使用已经不能访问的对象,从而防止程序设计错误的出现。此外,旧的浏览器(如 IE/MAC)没有全面的无用存储单元收集程序,所以在卸载页面时,对象可能不能被正确销毁。废除对象和它的所有特性是确保内存使用正确的最好方法。

注意:废除对象的所有引用时要当心。如果一个对象有两个或更多引用,则要正确废除该对象,必须将其所有引用都设置为 null。

结语:上述几种创建类的方式是目前的主要做法,至于选择哪种,一般都会是混合的构造函数/原型方式、动态原型方法,不过笔者最常用的是前者,因为笔者认为大可不必在意这一丁点的视觉效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值