JavaScript面向对象编程

收藏

JavaScript面向对象编程

  • 主要内容纲要

  1. 什么是 面向对象

  2. 通过JavaScript中内置对象的分析,介绍JavaScript中 对象的初始化 过程

  3. 如何 自定义类

  4. 自定义类如何实现类的 继承 (混入)

何谓面向对象

对象的定义是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。也有的定义为“一切都是对象”然而面向对象也不能简单的等价理解成面向任何事物编程,面对一切编程?开玩笑,呵呵。因此面向对象这个对象,指的是客体。所谓客体是指客观存在的对象实体和主观抽象的概念。

在递归的四个要素中,第四个要素:

合成效益法测:同样的一件事情不要重复做很多事,这样就摒弃了编程魅力之精髓。

我们可能每天都在重复做着同样一件事情,例如以下操作:

  • 数据库的CRUD

  • html、css中相同功能代码的编写

  • Java等面向对象语言中同一功能类的设计

如果我们使用常规方法,代码的编写量往往会很多,如果运用面向对象思想,相关问题就会得到简化。

  • 数据库可采用orm(object relative model)框架,如Java中的hibernate、mybatis等框架,致使我们将侧重点放在了功能的实现,数据库的sql抽象为了对类的操作。

  • html、css中,也有了类的概念,通过继承(混入)思想,可以实现高可用、低耦合的代码,例如pug等模板技术,sass、less、stylus等css预处理器。

  • Java面向对象的三大特性以及五项基本原则将面向对象思想表现的淋漓尽致。

正因为如此,面向对象编程的思想显得尤为重要。

再如物理学中对于对象的理解:世上的一切事物我们都可将之抽象,分类,而装入我们抽象词典中,每一个抽象个体便是一个 对象 ,有相同性质的对象抽象为  。

JavaScript内置对象的分析,深入JavaScript中对象的初始化过程

构造器的概念

JavaScript内置对象包括以下: String Number Boolean Function Date RegExp Math JSON  。

其中 Math JSON 属于 对象 ,而其他均属于 对象构造器 。使用以下代码进行验证:

 
					

1

2

 
					

console .log( typeof String ); // function

console .log( typeof JSON ); // object

这些构造器不仅能够使用  new关键字实例化  对象,还能起到  转换类型  的作用

 
					

1

2

3

4

5

 
					

var fn = Function ( 'console.log(1)' );

fn(); // 1

var date = Date ();

var arr1 = Array ( 2 ) // [ , ]

var arr2 = Array ( '1,2' ) // [1,2]

上面叙述的是从正向出发,那么逆向呢?

 
					

1

2

 
					

var date = new Date ();

console .log(date.constructor); // [Function: Date] node环境中

但是,这种检测方式不确定的,因为在浏览器环境下中,以上代码打印的结果却又是function Date() { [native code] },我们为了统一,全部使用 Object的原型方法toString 进行值的转换,结果为:

 
					

1

2

3

4

5

 
					

var date = new Date ();

Object .prototype.toString.call(date.constructor); // [object Function]

// 通过这种方法查看某一对象的具体类型

Object .prototype.toString.call( new Array ); // object

Object .prototype.toString.call( new Array ( 1 )); // [object Array]

我们还可以使用 instanceof 查看某个对象由那个类实例化而来

 
					

1

2

 
					

var date = new Date ();

date instanceof Date ; // true

自定义类

定义类的构造方法

 
					

1

2

3

4

5

6

7

8

9

 
					

var User = function ( ) {

this .name = name;

  this .setName = function ( name ) {

this .name = name;

  };

  this .getName = function ( ) {

return this .name;

  }

};

通过以上,我们就构造了User这样一个类的构造器,接着我们就可以初始化对象了。

对象的初始化

 
					

1

2

3

 
					

var user = new User();

user.setName( "walker" );

user.getName() // walker

那如果我们的方法在同一类初始化的很多对象中都有呢?

这时候就有了原型方法,原型继承的思想。

原型方法

 
					

1

2

3

 
					

User.prototype.show = function ( ) {

console .log( this .name);

};

所有该类实例化的对象都可以直接使用user.show()

原型继承中prototype和__proto__的关系,各自的功能

  • prototype是原型链,是传递 “遗传基因”

  • __proto__是实例化出的对象访问自己构造器所表征类的所有特征

  • 换句话说:对象调用__proto__属性可以访问其类的prototype对象

    又或者说,对象的__proto__对象指向实例化其类的prototype对象

    这一条链直到Object这个跟对象处截止。

  • 所有类的__proto__指向Function的prototype

  • 类的prototype的__proto__均指向上一父级的prototype

  • Object类的prototype因为是顶层,因此它的__proto__为null

  • 对象的__proto__均指向其类的prototype

关系图如下:

JavaScript中对象实例化的步骤

创建类并实例化一个对象

先来看看我们每天写的面向对象编程的代码:

 
					

1

2

 
					

var User = function ( ) {};

var user = new User();

在我们看来,简单的面向对象其实就是这么两行代码,其实不然,在JavaScript内部,对象的创建可没有这么简单哦。JavaScript对象创建的过程可概括如下:

 
					

1

2

3

4

5

6

7

8

9

10

 
					

// 生成Object对象(这就印证了为何所有的类都是Object的子类)

var obj = new Object ();

//  指定原型

obj.__proto__ = User.prototype;

// 调用构造器

User.call(obj);

//  如果有参数

User.call(obj,param1);

牢记这三个初始化步骤,以后开发中会使用这种思想

 
					

1

2

3

4

 
					

// var user = {};

var user = new Object ();

user.__proto__ = User.prototype;

User.call(user, 'walker' );

开发中该思想的应用

 
					

1

2

3

 
					

var user = {}; // 其实就是new Object();

user.__proto__ = User.prototype;

User.call(user, 'walker' );

自定义类如何实现类的继承

借用对象属性

 
					

1

2

3

4

5

 
					

var User = function ( ) {};

var VIPPerson = function ( ) {};

//  借用User实例化对象的属性和方法

VIPPerson.prototype = new User();

var vip = new VIPPerson();

借用原型属性和方法

 
					

1

2

3

4

 
					

var User = function ( ) {};

var Person = function ( ) {};

//  只是借用了User类的原型属性与方法

Person.prototype = User.prototype;

当然这种形式还存在一定问题,因为对象存储于 堆内存 ,Person.prototype只是对其引用,会相互影响值。

临时构造对象来解决这个问题:

 
					

1

2

3

4

5

6

 
					

var User = function ( ) {};

var Person = function ( ) {};

//  定义

var F = function ( ) {};

F.prototype = Person.prototype;

User.prototype = new F();

借用构造器

 
					

1

2

3

4

5

6

 
					

var User = function ( ) {};

var Person = function ( ) {

  //  借用构造器

  User.call( this );

};

Person.prototype = new User();

以上继承形式中,没有去关心类的构造器,我们为了出现偏差,在指定借用了prototype后,也要重新指定constructor。

 
					

1

2

3

4

5

 
					

var User = function ( ) {};

var Person = function ( ) {};

Person.prototype = new User();

//  指明Person类的构造器是Person

Person.prototype.constructor = Person;

评论(0条)

请登录后评论