码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-05-12 19:40:17      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

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 来自原型






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

标签:

原文地址:http://blog.csdn.net/believejava/article/details/51351010

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!