JavaScript面向对象设计

Javascript中的对象并不像传统编程语言中的对象一样,ECMAScript规范把对象定义为:无序属性的集合,其属性可以包含基本值、对象或函数

也就是说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。所以可以把Javascript对象想象成散列表即一组名值对,其值可以使数据或函数。每个对象都是基于一种引用类型创建的,可以使内置类型也可以使自定义类型

【创建对象】

 1  //创建一个对象,它拥有三个属性和一个方法
 2         var person=new Object();
 3         person.name="Jack";
 4         person.age=27;
 5         person.job="Software Engineer";
 6         person.sayName=function(){
 7             document.write(this.name);
 8         };
 9         //用对象字面量法创建对象
10         var person={
11             name:"Jack",
12             age:27,
13             job:"Software Engineer",
14             sayName:function(){
15                 document.write(this.name);
16             }
17         };

【属性的类型】 

在ECMAScript中有两种属性:数据属性和访问器属性。

数据属性

数据属性是包含一个数据值的位置,在这个位置可以读取和写入值,数据属性有4个描述其行为的特征

属性的特征
属性 _表示默认值 说明
[[Configurable]] true,false 能否通过delete删除属性从而重新定义属性
能否修改属性的特性
能否把属性修改为访问器属性
[[Enumerable]] true,false 能否通过for-in循环返回属性
[[Writable]] true,false 能否修改属性的值
[[Value]] undefined,false 包含这个属性的数据值

在上面创建person对象,它的属性特征[[Configurable]]、[[Enumerable]]、[[Writable]]的值都为true,[[Value]]即为属性的数据值

修改默认的属性的特征:

使用ECMAScript 5的defineProperty()方法可以修改属性的默认特性。如下

1 //修改属性的默认特性
2         var person={}; //字面量表示法创建空对象
3         Object.defineProperty(person,"name",{
4             writable:false,
5             value:"Jack"
6         });
7         document.write(person.name);
8         person.name="Tom"; //修改属性的值
9         document.write(person.name);

defineProperty()方法接受三个参数:属性所在的对象,属性名称和一个描述对象。上面代码修改了name属性的默认特性,使得writable:false即不能修改属性的值。所以,当打算把person.name="Tom"; 时在非严格模式下赋值操作被忽略,在严格操作模式下,会发生错误

【 常用的设计模式】

工厂模式

工厂模式抽象了创建具体对象的过程,由于在Javascript中没有类,所以依靠的是函数来模拟,即用函数来封装以特定接口创建对象的细节

 1 //用工厂模式创建对象
 2         function createPerson(name,age,address){
 3             var o=new Object();
 4             o.name=name;
 5             o.age=age;
 6             o.address=address;
 7             o.sayName=function(){
 8                 alert(this.name);
 9             };
10             return o;
11 
12         }
13         var person1=createPerson("Jack",29,"NanJing");
14         var person2=createPerson("Tom",25,"Suzhou");

可以无数次的调用这个函数,它每次都会返回一个对象,这个对象有三个属性和一个方法。

构造函数模式

Javascript中内置的构造函数原本是用来创建特别类型的对象,这些利用构造函数创建的对象,都具有默认的属性和方法, 但也可以自定义构造函数,从而自定义对象的属性和方法

 1  function Person(name,age,address){
 2             this.name=name;
 3             this.age=age;
 4             this.address=address;
 5             this.sayName=function(){
 6                 alert(this.name);
 7             };
 8         }
 9         var person1=new Person("Jack",29,"NanJing");
10         var person2=new Person("Tom",25,"Suzhou");

 根据惯例非构造函数首字母一般小写,构造函数的首字母应该大写,以示区别构造函数本身也是函数,只不过是用来创建对象罢了。调用构造函数创建对象会经历四个过程

一.创建一个新对象

二.将构造函数的作用域赋给新对象

三.执行构造函数中的代码

四.返回新对象

需要注意的是自定义的类型最终也是Object对象的实例,因为所有对象均继承自Object对象

构造函数也可以当做普通函数使用

构造函数与普通函数的区别就在调用方式上不一样,定义构造函数与普通函数的定义方法是一致的。对于任何函数使用new操作符调用即被当做构造函数使用,不使用new操作调用即是普通函数。下面是构造函数的几种调用方式

 1 //定义函数
 2         function Person(name, age, address) {
 3             this.name = name;
 4             this.age = age;
 5             this.address = address;
 6             this.sayName = function () {
 7                 alert(this.name);
 8             };
 9         }
10         //当构造函数来调用
11         var person1 = new Person("Jack", 29, "NanJing");
12         var person2 = new Person("Tom", 25, "Suzhou");
13         alert(person1.sayName());
14         //作为普通函数调用
15         Person("Lucy", 21, "BeiJing");  //添加到window
16         window.sayName();
17         //在另一个对象的作用域中调用
18         var p = new Object();
19         Person.call(o, "Justin", 22, "ShangHai");
20         o.sayName();

原型模式

在Javascript中每个函数都有一个prototype属性(函数是有属性的,因为函数式对象),这个属性是一个指针,指向一个对象,这个对象的作用:包含特定类型所有实例的方法和属性。也就是说无论何时只要创建一个新函数,引擎就会根据一定的规则创建一个原型属性prototype,这个原型属性指向原型对象,默认情况下所有原型对象都会自动获得一个constructor构造函数属性

  

原文地址:https://www.cnblogs.com/tao-zi/p/3941428.html