javascript 面向对象程序设计 (摘自js高级程序设计)

来源:互联网 发布:网络空间主权 编辑:程序博客网 时间:2024/06/06 05:35

ECMAScript 中没有的概念。

ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值,对象或者函数。”,对象是一组没有特定顺序的值。可以把对象想象成为散列表,无非就是一组名值对,其中值就是数据或者函数。

每个对象都是基于一个引用类型(原生类型/自定义类型)创建的。

创建对象的几种方式:

1. 创建一个object实例,然后为它添加属性和方法

var person = new Object();        person.name = "da huang";        person.age = 18;        person.job = "software developer";        person.sayName = function (){            alert (this.name);        }        person.sayName();
缺点:使用同一个接口创建很多对象,会产生大量的重复代码。

2. 工厂模式

考虑到ECMAScript 无法创建类,故用函数来封装以特定接口创建对象的细节

function createPerson(name,age,job) {            var o = new Object();            o.name = name;            o.age = age;            o.job = job;            o.sayName = function (){                alert (this.name);            };            return o;        }        var person1 = createPerson("Li Lei", 19, "PHD");        var person2 = createPerson("Da Huang", 18, "software developer");        person1.sayName();        person2.sayName();
特点:工厂模式虽然解决了创建多个相似对象的问题,但是,却没有解决对象识别的问题(即怎样知道一个对象的类型)。
3. 构造函数模式

ECMAScript中的构造函数可以用来创建特定类型的对象。像array和object这样的原生构造函数,会自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

// 构造函数        function Person(name, age, job) {            this.name = name;            this.age = age;            this.job = job;            this.sayName = function () {                alert(this.name);            }        }        var person1 = new Person("Li Lei", 19, "PHD");        var person2 = new Person("Da Huang", 18, "software developer");        person1.sayName();        person2.sayName();        alert(person1 instanceof Person);// true        alert(person1 instanceof Object);// true


与工厂模式的区别:

  • 没有显示地创建对象;
  • 直接将属性和方法赋值给this;
  • 没有return语句;
  • Person中的P大写(惯例:构造函数都应该以一个大写字母开头);
  • 创建新实例,必须使用new操作符。
特点:以这种方式定义的构造函数,可以将它的实例标志为一种特定的类型,这正是构造函数胜于工厂模式的地方使用构造函数的主要问题,是每个方法都要在实例上重新创建一遍,这个问题可以通过使用原型模式来解决。构造函数默认是定义在Global对象(浏览器中是window对象)中,instanceof和contructor属性始终在全局作用域中查询构造函数。

上面的person1和person2都有contructor属性,constructor属性最初是用来标志对象类型的,但是,提到监测对象,还是instanceof操作符更靠谱一点。person1既是Person实例,又是Object对象,是因为所有对象均继承自Object。

将构造函数作为函数

构造函数与其他函数的唯一区别,在于调用方式不同。任何函数只要通过new来调用,那它就可以作为构造函数;任何函数如果不通过new操作符调用,那它跟普通函数没什么两样。

//构造函数方式调用        var person1 = new Person("Li Lei", 19, "PHD");        person1.sayName();        //普通函数方式调用        Person("Yuan Jie", 18, "software developer");        window.sayName();        //在另一个对象中调用        var o = new Object();        Person.call(o,"Li Lei", 19, "software developer");        o.sayName();
不使用new操作符调用Person(),属性和方法都被添加到了window对象。当在全局作用域调用一个函数时,this对象总是指向Global对象(浏览器中是window对象),因此,在调用完函数后,可以通过window对象来调用sayName(),也可以通过call()(apply())在某个特殊对象的作用域中调用Person() 函数,这里在o的作用域中调用,因此调用后,o就拥有了所有属性和方法。

4. 原型模式

// 原型模式        function Person(){        }        Person.prototype.name = "Da Huang";        Person.prototype.age = 18;        Person.prototype.sayName = function(){            alert(this.name);        }        var person1 = new Person();        person1.sayName();// Da huang 来自原型        person1.name = "Li Lei";        person1.sayName(); //Li Lei 来自实例        person1.name = null;        if (person1.name == null) ;            alert("person1.name == null");// person1.name == null 来自实例        delete person1.name;        person1.sayName(); // Da Huang 来自原型        var person2 = new Person();        person2.sayName(); // Da Huang 来自原型

未完待续!!!





0 0
原创粉丝点击