美文网首页
ECMAScript 面向对象

ECMAScript 面向对象

作者: 耦耦 | 来源:发表于2018-01-02 09:21 被阅读10次

一、ECMAScript 面向对象技术


1、面向对象语言的要求

一种面向对象语言需要向开发者提供四种基本能力:

  • 封装 -- 把相关的信息(无论数据或方法)存储在对象中的能力
  • 聚集 -- 把一个对象存储在另一个对象内的能力
  • 继承 -- 由另一个类(或多个类)得来类的属性和方法的能力
  • 多态 -- 编写能以多种方法运行的函数或方法的能力
    ECMAScript 支持这些要求,因此可被是看做面向对象的。

2、对象的构成

在 ECMAScript 中,对象由特性(attribute)构成,特性可以是原始值,也可以是引用值。如果特性存放的是函数,它将被看作对象的方法(method),否则该特性被看作对象的属性(property)。

二、ECMAScript 对象应用


1、声明和实例化

对象的创建方式是用关键字 new后面跟上实例化的类的名字:

var oObject = new Object();
var oStringObject = new String();

第一行代码创建了 Object 类的一个实例,并把它存储到变量 oObject 中。第二行代码创建了 String 类的一个实例,把它存储在变量 oStringObject 中。如果构造函数无参数,括号则不是必需的。因此可以采用下面的形式重写上面的两行代码:

var oObject = new Object;
var oStringObject = new String;

2、对象引用

在 ECMAScript 中,不能访问对象的物理表示,只能访问对象的引用。每次创建对象,存储在变量中的都是该对象的引用,而不是对象本身。

3、对象废除

ECMAScript 拥有无用存储单元收集程序(garbage collection routine),意味着不必专门销毁对象来释放内存。
把对象的所有引用都设置为 null,可以强制性地废除对象。例如:

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

旧的浏览器(如 IE/MAC)没有全面的无用存储单元收集程序,所以在卸载页面时,对象可能不能被正确销毁。废除对象和它的所有特性是确保内存使用正确的最好方法。

4、早绑定和晚绑定

所谓绑定(binding),即把对象的接口与对象实例结合在一起的方法。

早绑定(early binding)是指在实例化对象之前定义它的属性和方法,这样编译器或解释程序就能够提前转换机器代码。在 Java 和 Visual Basic 这样的语言中,有了早绑定,就可以在开发环境中使用 IntelliSense(即给开发者提供对象中属性和方法列表的功能)。ECMAScript 不是强类型语言,所以不支持早绑定。

晚绑定(late binding)指的是编译器或解释程序在运行前,不知道对象的类型。使用晚绑定,无需检查对象的类型,只需检查对象是否支持属性和方法即可。ECMAScript 中的所有变量都采用晚绑定方法。这样就允许执行大量的对象操作,而无任何惩罚。

三、ECMAScript 对象类型


在 ECMAScript 中,所有对象并非同等创建的。
一般来说,可以创建并使用的对象有三种:本地对象、内置对象和宿主对象。

1、本地对象

ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。简单来说,本地对象就是 ECMA-262 定义的类(引用类型)。它们包括:

  • Object
  • Function
  • Array
  • String
  • Boolean
  • Number
  • Date
  • RegExp
  • Error
  • EvalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError

2、内置对象

  • 定义:
    由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。

这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 GlobalMath (它们也是本地对象,根据定义,每个内置对象都是本地对象)。

3、宿主对象

所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。
所有 BOM 和 DOM 对象都是宿主对象。

四、ECMAScript 对象作用域


作用域指的是变量的适用范围。

1、公用、私有和受保护作用域

  • 概念
    在传统的面向对象程序设计中,主要关注于公用和私有作用域。公用作用域中的对象属性可以从对象外部访问,即开发者创建对象的实例后,就可使用它的公用属性。而私有作用域中的属性只能在对象内部访问,即对于外部世界来说,这些属性并不存在。这意味着如果类定义了私有属性和方法,则它的子类也不能访问这些属性和方法。

    受保护作用域也是用于定义私有的属性和方法,只是这些属性和方法还能被其子类访问。

2、ECMAScript 只有公用作用域

因为 ECMAScript 中只存在一种作用域 - 公用作用域。ECMAScript 中的所有对象的所有属性和方法都是公用的。所有属性和方法默认都是公用的!

3、ECMAScript 没有静态作用域

严格来说,ECMAScript 并没有静态作用域。不过,它可以给构造函数提供属性和方法。还记得吗,构造函数只是函数。函数是对象,对象可以有属性和方法。例如:

function sayHello() {
  alert("hello");
}

sayHello.alternate = function() {
  alert("hi");
}

sayHello();     //输出 "hello"
sayHello.alternate();   //输出 "hi"

3、关键字 this

  • this 的功能
    在 ECMAScript 中,要掌握的最重要的概念之一是关键字 this 的用法,它用在对象的方法中。关键字 this 总是指向调用该方法的对象,例如:
var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
  alert(this.color);
};

oCar.showColor();       //输出 "red"

五、ECMAScript 定义类或对象

1、原始的方式

因为对象的属性可以在对象创建后动态定义,所有许多开发者都在 JavaScript 最初引入时编写类似下面的代码:

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

这里有一个问题,就是可能需要创建多个 car 的实例。

2、解决方案:工厂方式

要解决该问题,开发者创造了能创建并返回特定类型的对象的工厂函数(factory function)。

例如,函数 createCar() 可用于封装前面列出的创建 car 对象的操作:

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

var oCar1 = createCar();
var oCar2 = createCar();

通过这种方法,我们可以很容易地创建 car 对象的两个版本(oCar1 和 oCar2),它们的属性完全一样。

3、为函数传递参数

我们还可以修改 createCar() 函数,给它传递各个属性的默认值,而不是简单地赋予属性默认值:

function createCar(sColor,iDoors,iMpg) {
  var oTempCar = new Object;
  oTempCar.color = sColor;
  oTempCar.doors = iDoors;
  oTempCar.mpg = iMpg;
  oTempCar.showColor = function() {
    alert(this.color);
  };
  return oTempCar;
}

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

oCar1.showColor();      //输出 "red"
oCar2.showColor();      //输出 "blue"

给 createCar() 函数加上参数,即可为要创建的 car 对象的 color、doors 和 mpg 属性赋值。这使两个对象具有相同的属性,却有不同的属性值。

4、构造函数方式

创建构造函数就像创建工厂函数一样容易。第一步选择类名,即构造函数的名字。根据惯例,这个名字的首字母大写,以使它与首字母通常是小写的变量名分开。除了这点不同,构造函数看起来很像工厂函数。请考虑下面的例子:

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);

5、原型方式

该方式利用了对象的 prototype 属性,可以把它看成创建新对象所依赖的原型。

这里,首先用空构造函数来设置类名。然后所有的属性和方法都被直接赋予 prototype 属性。我们重写了前面的例子,代码如下:

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();

5、原型方式的问题

构造函数没有参数。使用原型方式,不能通过给构造函数传递参数来初始化属性的值。

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

联合使用构造函数和原型方式,就可像用其他程序设计语言一样创建对象。这种概念非常简单,即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果是,所有函数都只创建一次,而每个对象都具有自己的对象属性实例。

我们重写了前面的例子,代码如下:

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"

参考资料


【1.ECMAScript 面向对象】http://www.w3school.com.cn/js/pro_js_object_oriented.asp

相关文章

  • ECMAScript 面向对象

    一、ECMAScript 面向对象技术 1、面向对象语言的要求 一种面向对象语言需要向开发者提供四种基本能力: 封...

  • JavaScript之对象

    什么是面向对象: ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语...

  • ECMAScript 6面向对象

    ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定...

  • 02.ECMAScript面向对象

    Javascript入门 字符串 1.字符串的创建 1.1 字面量 1.2 使用构造方法 注意: 使用字面量创建的...

  • 理解JS的面向对象,理解new,new之后都做了什么

    ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就...

  • 面向对象不得不说二三事(1)

    1、ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,...

  • JS面向对象、JQuery选择器

    ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就...

  • 面向对象与原型

    ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就是...

  • 你有“对象”吗

    ECMAScript是一门面向对象的编程语言,它基于原型,以对象作为其核心概念。(对象很重要,无论对编程语言,还是...

  • JavaScript高级程序设计(第3版) 笔记

    第六章 面向对象的程序设计 6.1 理解对象 6.1.1 属性类型 ECMAScript 中有两种属性: 数据属性...

网友评论

      本文标题:ECMAScript 面向对象

      本文链接:https://www.haomeiwen.com/subject/gvkbwxtx.html