ECMAScript面向对象

来源:互联网 发布:虚荣辅助软件 编辑:程序博客网 时间:2024/05/17 03:51

面向对象

  • 对象

    1. JS定义对象为“属性的无序集合”
    2. 基于代码的名词表示
    1. 每个对象都由类定义
  • 实例

    1. 对象称为类的实例。
    2. 由类创建对象实例的过程叫做实例化(instantiation)
  • ECMAScript中的类

    1. 没有类的概念
    2. 对象定义为对象的配方
    3. 大多数时候,所说的类等价于对象定义
  • 面向对象语言的要求

    1. 封装
    2. 聚集:把一个对象存储在另一个对象内的能力
    3. 继承
    4. 多态
  • 对象的构成

    1. JS中,对象由特性构成
    2. 特性为原始值或引用值
    3. 特性为函数,看作对象的方法
    4. 否则,看作对象的属性

对象的应用

  • 对象的创建和销毁都在JS执行过程中发生
  • 声明和实例化
    new + ClassName
var oObject = new Object();var oStringObject = new String();
  • 对象引用

    1. 不能访问对象的物理表示
    2. 只能访问对象的引用
    3. 存储在对应变量中的,是对象的引用,而不是本身
  • 对象废除

    1. JS有无用存储单元程序(garbage collection routinue)
    2. 当一个对象的引用没有是,该对象被废除。
    3. 运行GCR程序时,废除的对象都被销毁。
    4. 函数执行代码后,都会调用GCR
    5. 一些其他不可预知的清空下,也会调用GCR
    6. 把对象的所有引用设置为null时,可以强制废除对象
    7. 如果一个对象有多个引用,必须将所有引用都设置Null
  • 早绑定和晚绑定

    1. 绑定(binding),把对象的接口与对象的实例结合在一起的方法
    2. 早绑定(early binding),指在实例化对象前,定义它的属性和方法。JS不支持早绑定.
    3. 晚绑定(late binding),在运行前,不知道对象的类型,运行时进行判断。JS所有变量都采用晚绑定。

ECMAScript对象类型

  • 对象类型

    1. 本地对象
    2. 内置对象
    3. 宿主对象
  • 本地对象

    1. 独立于宿主环境的JS实现提供的对象。
    2. 简单来说,本地对象是ECMA-262定义的类
ObjectFunctionArrayStringBooleanNumberDateRegExpErrorEvalErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
  • 内置对象
    1. 为由ECMAScript实现提供,独立于宿主环境的所有对象
    2. ECMA-262定义了两个内置对象
GlobalMath
  • 宿主对象
    1. 所有非本地对象
    2. 由宿主环境提供的对象
    3. 如BOM和DOM

对象作用域

  • 作用域:变量的使用范围

  • 公有、私有、受保护

    1. JS只有公有作用域
  • 如何私有?

    1. JS中并不能真正私有,只能假装私有
    2. obj.color = “blue” 表示该属性私有
  • 静态作用域

    1. JS中没有静态作用域
  • 关键字this

    1. JS中this指向调用该方法的对象

JS中定义类或对象

  • 工厂方式
    原始方式
var object = new Object();o.name = "linduo";o.age = "5";o.show() = function() {    // ...}

问题,无法便捷的创建多个实例

工厂方式
可以创建并返回特定类型的对象的工厂函数

function createPerson() {    var person = new Object();    person.name = "linduo";    person.age = "5";    person.show() = function() {        // ...    }    return person;}var p1 = new createPerson();var p2 = new createPerson();

改进
在函数外定义对象的方法,使方法在内存中只有一份拷贝

function showColor() {    // ...}function createPerson(){    // ...    person.showColor = showColor;    return person ;}

构造函数方式

  • 构造函数
function person () {    this.xxx= xxx;    // ...    this.show() = function() {        // ...    }}

* 问题:重复生成函数*

  • 原型方式
function person () {}person .prototype.name= "linduo";person .prototype.age = 5;person .prototype.color = yellow;person .prototype.showColor = function() {  alert(this.color);};var P1 = new person ();var P2 = new person ();

问题:构造函数无参数,属性为引用类型时,属性被多个实例共享,修改一个,其他实例的该属性也改变

  • 改进:构造函数+原型
    1. 构造函数定义对象的所有非函数属性
    2. 原型方式定义对象的函数属性
function person (name,age,color) {  this.name= name;  this.age= age;  this.color= color;  this.adress= new Array("CHN","SY");}person.prototype.showColor = function() {  alert(this.color);};

JS开发时,采用的主要方式

  • 动态原型方法
    1. 视觉上,更向面向对象语言
function person(name,age,color) {  this.name = name;  this.age = age;  this.color = color;  this.adress= new Array("CHN","SY");  if (typeof person._initialized == "undefined") {    person.prototype.showColor = function() {      alert(this.color);    };    person._initialized = true;  }}

可以保证函数只存在一份

修改对象

  • 创建新方法
    可以使用原型为已有类添加新方法
Number.prototype.toHexString = function() {  return this.toString(16);};
  1. 重命名已有方法,使用更易理解的函数名,封装相关动作的函数
  2. 覆盖原有方法,使用同名函数覆盖已有方法,原方法不可以在调用。可以使用以下方法,在覆盖前,保存原有方法。
// 通过originalToString()可以调用原有方法Function.prototype.originalToString = Function.prototype.toString;Function.prototype.toString = function() {  if (this.originalToString().length > 100) {    return "Function too long to display.";  } else {    return this.originalToString();  }};

为本地对象添加新方法,在Object对象的prototype属性上定义。