JavaScript的对象回顾归纳(一)

1 .面向对象

面向对象是存在于软件工程中的一种思想,一种方法,包括分析阶段、设计阶段和开发阶段等。由于面向过程在解决问题之前需要对所解决的问题要有较为细致的了解,然后把问题分解为若干个小问题再解决,在问题复杂度较高的情况下,这么做就有点为难我胖虎了。但我觉得这种方法接近于人类的一般思维,比较容易理解和掌握。

而面向对象则是从面向过程相反的方向出发,从问题的局部进行分析,逐渐加深对系统的理解,随着需求的变化和新的理解,对现有系统进行拓展。

面向对象方法的主要有以下几个特性:

  • 抽象性

要用面向对象的分析问题必须首先会“抽象”问题,找出问题的本质属性,就是最不容易发生改变的特性。比如说,要设计一款汽车展示软件,就应该抽象出汽车的种类、外形、性能等方面的通性,例如一辆汽车至少有一台发动机,四个轮子这些原有的属性,还有换挡、刹车这些行为(也就是方法)。创建类的过程就是将具有相似属性(或具有通性)的一类事物的抽象。

  • 继承性

继承可以理解为对某一属性的扩展。比如,汽车有4轮的,当然也有比4轮多的,在描述多轮汽车时,我们可以派生出一个新的类(子类)来描述这一类汽车,然后新继承了原有的类(父类)的其他特性。继承是好处是可以大大减少重复编码的工作量,因为不需要修改的地方直接从基(父)类继承而来就行了。

  • 多态性

多态性是指相同的操作方法带来的不同结果。从形式上来说,多态分为两种,分别为重载覆盖

覆盖就是子类对父类原有的一些行为作了修改,虽然行为相同,但结果不同,例如改进性能的同系列车型就比原来的车型在某些方面表现优异。

重载是指某一个对象的相同行为导致了不同的结果。典型的例子就是”+”号,它既可以作为算数运算的加号,还可以作为字符串的连接符。多态一方面加强了程序的灵活性和适应性,另一方面也可以减少编码的工作量。

1.1 类

类是用来描述抽象的一种载体,它记录了哪些属性和行为是具有通性的。在大部分面向对象语言中,都有类(class)这个关键字(ECMAScript第三版规范只做保留字,并没有实现),用来创建用户自己的数据类型。例如汽车类或者其他什么类。例如:

class Car {
    String color;//属性
    void shift() {  //行为
        //换档
    }
}
//创建一个redCar对象
Car redCar = new Car();

不同的对象有不同有颜色,但是它们都有color属性,只是值不同而已。同样,换挡的行为也有不同的结果,这些对象总是拥有换挡的行为。可以看到一个类并不是一个单纯的数据集合,他还包括了行为,这是面向对象的另一个特点—-封装性。

封装是为了避免因程序相互影响而产生的变动影响,保证了局部的完整性。对封装体外部来说只需要关心这个模块能干什么事(行为),而对封装块内部的数据变化(属性)不需要了解,也不应该干预。封装就是为了减少各个模块间的依赖。

类是描述一类事物的共同属性,它是抽象的,没有具体含义的。而对象是类的实例。例如汽车是对这种机动工具的总称。而某人开的汽车就很具体了,它具有具体的颜色、大小、品牌等。面向对象语言的重要特性就是可以何以创建类,但遗憾的是ECMAScript中目前没有实现class,而只有对象。所以 ECMAScript 规范中把自己定义为“基于对象”的脚本语言,因而不能创建类,只能使用对象。实际上, ECMAScript 中也有这种类似于“类”的抽象化描述机制,只是具体的实现方法不同。

1.2 对象

对象从概念上讲,就是类的实现,把抽象的变为具体的,就像刚刚创建出的redCar那样。 ECMAScript 将对象定义为:无序属性的集合,属性可以是任何类型的值,包括其他对象或函数,当函数被当作对象属性时被叫做“方法”,也就是对象的行为。每个属性都可以没有或者拥有多种不同的特性。如下表:

数据属性
访问器属性

ECMAScript规范作为对象定义了很多内部属性,虽然这些书信只是针对语言的实现者来定义的,它们无法通过代码访问到,只能被运行代码的系统来访问,但了解这些属性可以更清楚的明白代码的含义。如下表:

对象的属性

1.3创建对象

语法:

var 对象名 = new 构造函数();
    //当构造函数不需要传递参数时,可以省略那一对小括号,但是不推荐这样做。
obj = new Objeict; //Objeict本身也是对象
alert ('Objeict对象的构造函数为:'+ obj.constructor);
alert ('Objeict对象的原型为:'+ Objeict.prototype);

1.4在 ECMAScript5 中创建对象

在 ECMAScript 第五版中,提供了新的定义对象的方法,使用这种方法,我们可以创建出具有只读特性或者不可删除特性的对象属性,甚至可以在对属性赋值前进行检测,但这里说的不是调用对象的时候检测。

var ken = Objeict.defineProperties({},{ sex: { value:’male’, writable:false //只读 }, weight: { set: function(w) { if(w>90) alert (‘r u kidding me…’); this.value = w; }, configurable:false } }); ken.sex = ‘female’; //严格模式下浏览器会报错 ken.weight = 100; //赋值时检测 Delete ken.weight; //在严格模式下浏览器会报错

1.5对象属性

  • 访问属性

无论是函数还是变量,作为对象的属性,都可以通过“.”号进行访问,如果对象的熟属性仍然是一个对象,那么还可以通过重复调用“.”号进行连续访问。例如:

var a = new Objeict;
    //显示对象a的constructior属性(对象)的prototype属性
alert(a.constructor.prototype);

但要注意的是,应尽量少的进行多级连续引用,这样可以防止由引用链中某个对象为空而导致的程序错误,例如:

//如果对象b或者c为null的话,将引发一个对象引用错误
a.b.c.d;

解决的办法就是在不确定的对象前使用if语句进行判断。

  • 添加属性

在 ECMAScript中,对象的属性都与普通的函数或其他变量一样,可以动态的生成。例如:

var a = new Objeict;
a.x = 1;  //生成函数属性
a ["func"] = function() {  //生成函数属性
   ++this.x;  //this表示对象a本身
}
a.func();
alert(a.x);  //显示为2

直接对指定的属性名赋值,就可以生成一个对象的属性,这可不是使用var关键字进行声明。

  • 删除属性

删除属性首先delete运算符。当然从资源释放的角度来说,只需要把删除的属性设置为null就可以了,这与对象的释放有关。例如:

var a = new Objeict;
a.x = new Objeict;
    //释放属性所引用的对象
a.x = null;

一旦一个对象不再被引用,那么这个对象所占用的空间就会被在自动释放掉了。

  • 释放对象
在任何编程语言中,释放不在使用的内存空间都会是很重要的一件事情。 ECMAScript像Java一样,提供了自shouji动回收内存的机制----垃圾收集器。垃圾收集是语言本身的一种机制,这种机制可以帮助在编码人员处理内存的分配。
程序通过new来申请内存空间(实例化对象),而垃圾收集器则是在对象不用释放内存空间。垃圾收集器是由脚本环境(浏览器)启动的。 对编码人员来讲,它是不可见的,但它会在后台自动运行,并且也只能自动运行在后台。它会监视程序中的对象使用情况,当对象不再使用时,垃圾收集器会自动地清除数据,释放内存空间。
即当对象不再被任何变量引用的时候,这个对象就不再被使用了,垃圾收集器就可以收回这个对象所在的内存空间了。
每当函数执行完毕,垃圾收集器都会释放函数中的局部变量,当然这不包括作为函数返回值返回的引用类型(对象)。例如:
function func() {
   var str = new String('局部变量');
   alert(str);
   var obj = new Objeict;
   return obj;
}
var obj2 = func();

函数执行后,String类型的局部变量str对象就被释放了,但Obj对象仍然被函数外部变量引用,无法释放。
垃圾收集器什么时候运行代码是无法控制的,但只要将变量赋值为null,就可以删除变量的引用,没有被引用的对象才会被收集。例如:

//创建变量
var obj = new Objeict();
var obj2 = obj;
//释放引用
var obj1 = null;
var obj2 = null;

代码中,同一个Objeict对象有两个引用,所以必须释放这两个引用,垃圾收集器才认为这个对象不再被使用。

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注