前端开发之面向对象

标签: 前端开发 | 发表时间:2012-10-19 10:39 | 作者:AllexWang
出处:http://ued.sina.com.cn

前端开发之面向对象

【零】 摘要 Index

面向对象的基本概念
面向对象的三个基本特征
Javascript 面向对象
* 对象封装
* 继承的实现
* 多态
实例讲解 (PADMAIL项目UI组件设计与实现)

【一】 面向对象的基本概念

面向对象的英文全称叫做Object Oriented,简称OO。OO其实包括OOA(Object Oriented
Analysis,面向对象分析)、OOD(Object Oriented Design,面向对象设计)和OOP(Object
Oriented Programming,面向对象的程序设计)。

通常所说的面向对象是指OOP, OOP是一种围绕真实世界的概念来组织模型的程序设计方法,它采用对象来描述问题空间的实体。在使用计算机解决问题时, 对象是作为计算机模拟真实世界的一个抽象,一个对象就是一个物理实体或逻辑实体,它反映了系统为之保存信息和(或)与它交互的能力。使其具有自己的属性和行为, 从而简化对复杂事物的描述,更有利于工程的可维护性和扩展性。

OOP同结构化程序设计相比最大的区别就在于: 前者首先关心的是所要处理的数据,而后者首先关心的是功能。

【二】 面向对象三个基本特征

封装 (Encapsulation) 将数据以及相关的操作组织在一起,成为独立的构件。外部无法直接访问这些封装了的数据,从而保证了这些数据的正确性。封装的目的是为了 内部数据表现形式和实现细节的隐藏,信息隐藏是为了减少系统各部分间的依赖性,各部分间必须通过明确的通道传送信息,也就是对象间的接口.这样一来,隐藏了部分内部的细节,极大方便系统的开发,维护和扩展。

继承 (Inheritance) 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它 提供了一种明确表述共性的方法。一个新类可以从现有的类中派生,这个过程称为类的继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。 派生类可以从它的基类那里继承方法和实例变量,并且派生类可以修改或增加新的方法使之更适合特殊的需求。继承性很好地解决了软件的可重用性问题。

多态 (Polymorphism) 多态是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是允许类与类之间相同方法名的指针得以调用, 这样很好地 解决了应用程序函数同名问题。实现多态,有二种方式,覆盖,重载。

【三】 Javascript 面向对象

javascript 本身是一种基于对象(object-based)的语言,我们日常编码过程中用到的所有东西几乎都是对象(Number,String,Boolean, etc,.)。但是,相对于一些流行的面向对象语言(C++,C#,java),它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class的概念。

Keyword: class, object, `this`, closure, constructor, prototype

几种对象封装的方法
继承
多态体现

之一、几种对象封装的方法

1. 对象封装 – 原始模式

假定我们把猫看成一个对象,它有”name”和”color”两个属性, “eat” 行为。

var Cat = {
    name: ''
    color: '',
    eat: function() {}
};

现在,我们需要根据这个原型对象的规格(schema),生成两个实例对象。

function eat() {
    console.log('I\'m eat fish');
}
var cat1 = {name: 'Kitty', color: 'white', eat: eat};
var cat1 = {name: 'Smokey', color: 'black', eat: eat};

// var cat2, cat3 ,...

不方便创建多个实例对象,扩展性差, 实例(cat1, cat2)之间找不到联系。…

2. 对象封装 – 构造函数模式

“构造函数”,就是一个普通函数,但是内部使用了 `this` 变量。对函数使用
`new` 运算符,就能生成实例,并且 `this` 变量会绑定在实例对象上。

使用构造器创建出来的对象会有一个 `constructor` 属性,指向它们的构造函数。
`Class` 只是一个模板,创建出来的来实例都是由模板生成。

比如,猫的原型对象现在可以这样写:

function Cat(name,color){
this.name = name;
this.color = color;
    this.eat = function() { console.log('eat fish'); };
}

var cat1 = new Cat('Kitty', 'white');
console.log(cat1.name); // Kitty
console.log(cat1 instanceof Cat); // TRUE
// 这时 cat1 实例会自动含有一个 `constructor` 属性,指向它们的构造函数 `Cat`。

var cat2 = Cat('Smokey', 'black');
console.log(cat2); // undefined

3. 对象封装 – Prototype 模式

`prototype` 是 `Function` 对象的一个属性,这个属性指向另一个对象。 这个对象的所有属性和方法,都会被构造函数的实例继承。
同时 `prototype` 又存在一个指向构造函数的引用 `constructor`,这样就成功的构成一个循环引用的原型链结构。

我们可以把那些不变的属性和方法,直接定义在 `prototype` 对象上, 节省内存开销。

function Cat(name, color) {
    this.name = name;
    this.color = color;
}
Cat.prototype.type = 'mammal';
Cat.prototype.eat = function() { console.log('eat fish'); };

var cat1 = new Cat('Kitty', 'white');
var cat2 = new Cat('Smokey', 'black');
console.log(cat1.type); // mammal
console.log(cat1.eat === cat2.eat);     // TRUE, same reference
console.log(cat1.constructor === Cat)   // TRUE, from Person.prototype

之二、继承 (Inheritance)

将持有共性特点的属性或行为抽象出一个基本类, 可以按不同层次结构的业务分组抽象出多个基础类。

Cat, Bird

继承

1. 继承 – 构造函数绑定

使用call或apply方法,将父对象的构造函数绑定在子对象上。

function Animal() {
    this.species = 'animal';
    this.sleep = function() { console.log('I\'m sleep at night'); };
}

function Cat(name, color) {
    this.name = name;
    this.color = color;
}

让`Cat` 继承 `Animal` 的特性:

/** @class Cat */
function Cat(name, color) {
    Animal.apply(this);
    this.name = name;
    this.color = color;
}
var cat1 = new Cat('Kitty', 'white');
cat1.sleep(); // I am sleep at night

2. 继承 – 原型链继承

如果”猫”的prototype对象,指向一个Animal的实例,那么所有”猫”的实例,就能继承Animal了。

/** @class Cat */
function Cat(name, color) {
    this.name = name;
    this.color = color;
}
Cat.prototype = new Animal;
Cat.prototype.eat = function() { console.log('fish is my delicious'); };

它相当于完全删除了prototype 对象原先的值,然后赋予一个新值

// 任何一个prototype对象都有一个constructor属性,指向它的构造函数
Cat.prototype.constructor = Cat; // fix prototype chains

var cat = new Cat('Kitty', 'white');
cat.eat();      // fish is my delicious
cat.sleep();    // I'm sleep at night'
console.log(cat instanceof Cat);    // TRUE
console.log(cat instanceof Animal); // TRUE

需要创建父类实列来实现 `prototype` 继承

3. 继承 (Inheritance) – 利用空对象作为中介实现原型继承

var F = function() {};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;

我们将上面的方法,封装成一个函数,便于使用。

function extend(ctor, superctor, px) {
    if (!superctor || !ctor) throw Error('extend failed, verify dependencies');
    var F = function() {};
    F.prototype = superctor.prototype;
    ctor.prototype = new F();
    ctor.prototype.constructor = ctor;
    ctor.superclass = superctor.prototype; // cache super class proto reference.
    if (px) { // extend class implements
        for (var k in px) {
            if (px.hasOwnProperty(k)) ctor.prototype[k] = px[k];
        }
    }
    return ctor;
}

4 继承 – 借住工具方法实现继承

/** @class Mammal */
extend(Cat, Animal, {
    eat: function() {
        Cat.superclass.eat.call(this); // call super method
        console.log('Also i like some ofther food, such as beef and more.');
    }
});

var cat = new Cat('Smokey', 'black');
cat.sleep();
cat.eat();
console.log(cat instanceof Animal);
console.log(cat instanceof Cat);

之三、多态

1. 多态 – 通过重写原型方法来实现方法重名调用

/** @class Cat */
extend(Cat, Animal, {
    eat: function() {
        Cat.superclass.eat.call(this); // call super method
        console.log('Also i like some ofther food, such as beef and more.');
    }
});

2. 多态 (Polymorphism) – 原型继承 `prototype` 链上的方法、属性查找

多态。

【四】总结 Summary
Constructor
Prototype
Inheritance

【幻灯片显示——前端开发之面向对象】

相关 [前端 开发 面向对象] 推荐:

前端开发之面向对象

- - 新浪UED
Javascript 面向对象. 实例讲解 (PADMAIL项目UI组件设计与实现). 【一】 面向对象的基本概念. 面向对象的英文全称叫做Object Oriented,简称OO. OO其实包括OOA(Object Oriented. Analysis,面向对象分析)、OOD(Object Oriented Design,面向对象设计)和OOP(Object.

面向对象的Shell脚本

- jejer - 酷壳 - CoolShell.cn
还记得以前那个用算素数的正则表达式吗. 编程这个世界太有趣了,总是能看到一些即别出心裁的东西. 你有没有想过在写Shell脚本的时候可以把你的变量和函数放到一个类中. 不要以为这不可能,这不,我在网上又看到了一个把Shell脚本整成面向对象的东西. Shell本来是不支持的,需要自己做点东西,能搞出这个事事的人真的是hacker啊.

拥抱原型面向对象编程

- - 博客 - 伯乐在线
来源: IBM DeveloperWorks. 简介: JavaScript 是最低级的 Web 编程接口,随处可见. 随着 Web 日益成为日常生活的一部分,JavaScript 也开始变得备受关注. JavaScript 是一个经常遭到误解的语言,被认为是一种玩具语言或者一种 “不成熟的 Java™ 语言”.

如此理解面向对象编程

- - 酷壳 - CoolShell.cn
从Rob Pike 的 Google+上的一个推看到了一篇叫《 Understanding Object Oriented Programming》的文章,我先把这篇文章简述一下,然后再说说老牌黑客Rob Pike的评论. 先看这篇教程是怎么来讲述OOP的. 它先给了下面这个问题,这个问题需要输出一段关于操作系统的文字:假设Unix很不错,Windows很差.

面向对象设计模式的核心法则

- tonytech - Michael`s blog
有本经典的书叫《设计模式》,讲了经典的21种设计模式,建议大家都看看. 就一个类而言,应该仅有一个引起它变化的原因. 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力. 这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏. 软件设计真正要做的许多内容,就是发现职责并把那些职责互相分离.

面向对象的 JavaScript 编程及其 Scope 处理

- zhibin - IBM developerWorks 中国 : Web development : Articles,Tutorials
在面向对象的 JavaScript 编程中,我们常常会将一些数据结构和操作封装成对象以达到继承和重用的目的. 然而层层封装和继承再加上 JavaScript 中特殊关键字 this 的使用,使得 JavaScript 当前运行 Context 看起来非常的混乱. 很多 developer 为了获取运行时正确的 Context,常常不得已将 function 或者 Object 声明在全局 Global Context 中.

看透面向对象的复用技术

- - 博客 - 伯乐在线
来源: RayChase 的博客. 本文翻译自 这篇文章,这篇文章写于1998年,作者是Scott Ambler,真的挺久远了. 看看上个世纪末的时候, 程序员的视角和观点. 想从面向对象复用技术中真正获益,你就必须理解不同种类的复用,并且自如地在不同场合下使用它们. 复用性是面向对象技术带来的很棒的潜在好处之一.

面向对象设计原则:不要STUPID,坚持GRASP和SOLID

- - CSDN博客架构设计推荐文章
不要STUPID,坚持GRASP和SOLID. 有人可能会说:这是描述设计原则的一个专业术语,由我们可爱的代码整洁之道传教者鲍勃(罗伯特C. 马丁)大叔提出,是一组用于指导我们如何写出“好代码”的原则. 在编程界充满了这样由单词首字母组成的缩略词. 其它类似的例子还有DRY(Don’t Repeat Yourself.

JavaScript 游戏中的面向对象的设计

- - 博客 - 伯乐在线
来源: IBM developerworks. 简介: 从程序角度考虑,许多 JavaScript 都基于循环和大量的 if/else 语句. 在本文中,我们可了解一种更聪明的做法 — 在 JavaScript 游戏中使用面向对象来设计. 本文将概述原型继承和使用 JavaScript 实现基本的面向对象的编程 (OOP).

面向对象设计的设计原则

- - 博客园_知识库
  在设计面向对象的程序的时,模式不是一定要套的,但是有一些原则最好是遵守. 这些原则已知的有七个,包括:开闭原则、里氏代换原则、依赖倒转原则、合成/聚合复用原则、迪米特法则、接口隔离原则,单一职责原则. Martin引入了SOLID的说法,包括了其中的五个原则. 另外两个,这里把他们算成额外的两个规则.