zoukankan      html  css  js  c++  java
  • 第十五章 面向对象与原型

      ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象(Object - Oriented,OO)的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。

    一、创建对象

      创建一个对象最简单的方式就是创建一个object的实例,然后再为他添加属性和方法。

      var person = new Object();

      person.name = "Nich";

      person.age = 27;

      person.job = "Software Engineer";

      

      person.sayName = function(){

        alert(this.name);

      }

      上面创建了一个对象,并且创建属性和方法,在 sayName() 方法里的this,就是代表 person 对象本身。

      1.属性类型

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

      数据属性包含一个数据值的位置。在这个位置可以读取和写入值。

      var person = {

        name : "Nich"

      };

      创建一个名为name的属性,为它指定的值是“Nich”。

      2.访问器属性

      访问器属性不包含数据值;它们包含一对 getter 和 setter 函数。在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时候,会调用 setter 函数并传入新值;

      访问器属性不能直接定义,必须使用 Object.defuneProperty()来定义。

    var book = {
          _year : 2013,
          edition : 1      
    };
    
    Object.defineProperty(book,"year",{
          get : function(){
                   return this._year; 
    },
          set : function(newValue){
                   if(newValue > 2013){
                      this._year = newValue;
                      this.edition += newValue - 2013;
    }
    }
      });    
    

      这里创建了一个book对象,并给它定义两个默认的属性。

      3.读取属性

      读取属性要用到 Object.getOwnPropertyDescriptor() 方法;

      

    var book = {};
    
    Object.defineProperties(book,{
    
              _year : {
                           value : 2013
                          },
              edition : {
                           value : 1
                          },
               year : {
                          get : function(){
                                  return this._year;
                         },
                set  : function(newValue){
                            if(newValue > 2013){
                               this._year = newValue;
                               this.edition += newValue -2013;
                            }
                         }
                 }    
      });
    
    
    var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
    alert(descriptor.value);           //2013
    alert(descriptor.confi gurable); //false
    

    二、工厂模式

      工厂模式是软件工程领域一种设计模式,这种模式抽象了创建具体对象的过程,考虑到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("Nice", 27 ,"Software Engineer");
    var person2 = createPerson("Greg", 29, "Doctor");
    

      工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。

      ECMAScript中可以采用构造函数(构造方法)可用来创建特定的对象。类型于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("Nice", 27 ,"Software Engineer");
    var person2 = new Person("Greg", 29, "Doctor");
    

      两个函数不同之处:

      1.没有显示的创建对象;

      2.直接将属性和方法赋给了this对象;

      3.没有return语句。

      构造函数的方法有一些规范:

      1.函数名和实例化构造名相同且大写,这么写有助于区分构造函数和普通函数;

      2.通过构造函数创建对象,必须使用new运算符。

      要创建Person的新实例,必须使用 new 操作符。这种方式调用构造函数经历了4个步骤:

      1.创建一个新对象;

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

      3.执行构造函数中的代码;

      4.返回新对象。

      关于this的使用,this其实就是代表当前作用域对象的引用。如果在全局范围this就代表window对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。

      构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函数,必须用new运算符来调用,否则就是普通函数。

      构造函数问题

      构造函数每次使用使用都需要实例重新创建一次,以上面一个例子:

      

    alert(person1.sayName == person2.sayName);  //false
    

      创建两个完全同样任务的Function实例是没有不要的;况且有 this 对象在,根本不用在执行代码前就把函数绑定到特定对象上面。

      

    function Person(name, age, job){
              this.name = name;
              this.age = age;
              this.job = job;
              this.sayName = sayName;
    }    
    
    var sayName=function() {
                        alert(this.name); 
    }
    
    var person1 = new Person("Nice", 27 ,"Software Engineer");
    var person2 = new Person("Greg", 29, "Doctor");
    alert(person1.sayName == person2.sayName);  //true

      

  • 相关阅读:
    5月做题计划(数据结构)
    SRM 545 DIV2
    6月做题计划(递归与分治)
    POJ 3121 The SetStack Computer
    struts2初步学习路线
    my97datepicker日历展示出现中文乱码的问题
    tomcat请求数据的编码设置
    STRUT2传递参数中文乱码解决方法
    js mine 类型javascripttext/javascript,application/javascript, and appliation/xjavascript
    eclipse内存设置参数
  • 原文地址:https://www.cnblogs.com/xchit/p/JavaScript_15.html
Copyright © 2011-2022 走看看