Javascript中的对象(一)

Javascript是基于对象模型设计的一种编程语言,它的核心(ECMAScript)具有非常强大和灵活的面向对象编程的能力。

  1. 什么是对象?

    在javascript中,对象是一个拥有属性和类型的独立实体。ECMA-262 把对象(object)定义为"属性的无序集合,每个属性存放一个原始值、对象或函数”。

    我们拿它和一个杯子做下类比。一个杯子是一个对象(物体),拥有属性。杯子有颜色,图案,重量,由什么材质构成等等。同样,javascript对象也有属性来定义它的特征。杯子也具有某些功能,比如说能够容纳一定量的液体。同理,Javascript对象也有方法来定义它的功能。

    所有的原生类型除了 null 与 undefined 之外都被当作对象。它们可以被赋予属性(某些类型的被赋予的属性不能被持久化),并且它们都有对象的全部特征。

  2. Javascript有哪些对象?

    JavaScript 拥有一系列预定义的对象和宿主应用提供的一些对象,在这里我们只介绍Javascript内置的对象,具体按照类别可以分成:

    • 全局常量: Infinity, NaN, undefined, null
    • 全局方法: eval(), isFinite(), isNaN(), parseFloat(), parseInt(),decodeURI(),decodeURIComponent(), encodeURI(), encodeURIComponent()
    • 基本对象:Object, Function, Boolean, Error, 
    • 数字日期:Number, Math, Date
    • 文字处理: String, RegExp
    • 数组集合: Array

    当然用户也可以创建对象。

  3. Javascript中对象怎么定义?

    从  JavaScript 1.2 之后,你可以通过对象初始化器(Object Initializer)创建对象。或者你可以创建一个构造函数并使用该函数和 new 操作符初始化对象。

    • 使用对象初始化器

      通过对象初始化器创建对象的语法如下:

      var obj = { property_1:   value_1,   // property_# may be an identifier...
                  2:   value_2,   // or a number...
                  // ...,
                  "property n": value_n }; // or a string

      这里 obj 是新对象的名称,每一个 property_i 是一个标识符(可以是一个名称、数字或字符串),并且每个 value_i 是一个其值将被赋予 property_的表达式。obj 与赋值是可选的;如果你不需要在其他地方引用对象,你就不需要将它赋给一个变量。(注意在接受一条语句的地方,你可能需要将对象定义文本括在括号里,从而避免将这些文本与块代码相混淆)

      对象初始化器是表达式,新的对象在这些表达式出现的地方被创建出来,所以说即使完全相同的对象初始化表达式所创建的出来的对象也是不等的。就好像调用new Object()创建不同的对象实体一样。

      下面列子创建出cup对象,具有三个属性。我们注意到属性design也是一个具有属性的对象。

          var Cup = {
              color: "white", //default value of properties
              weight: 0.5,
              material: "china",
              design: {
                  color: "pink",
                  mark: "rose"
              },
              fill: function (liquid, volumn) {
                  //todo
                  console.log("The " + this.color +  " and " + this.material +  " cup is filled with " + volumn + " litre " + liquid + ".");
              }
          }

      在Javascript 1.1版本以及之前版本,我们不能使用对象初始化器来创建对象,只能使用下面的方法来创建对象。

    • 使用构造函数创建对象

      你可以通过两步来创建对象:

      • 通过创建一个构造函数来定义对象的类型。首字母大写是非常普遍而且很恰当的惯用法。
      • 通过new创建对象实例。

      为了定义对象类型,为对象类型创建一个函数以声明类型的名称、属性和方法。例如,要创建一个cup对象,我们可以使用如下的函数:

          function Cup(color, weight, material, designColor, markImage) {
              this.color = color;
              this.weight = weight;
              this.material = material;
              this.design = { color: designColor, mark: markImage };
              this.fill = function (liquid, volumn) {
                  //todo
                  console.log("The " + this.color + "  and " + this.material + " cup is filled with" + volumn + " litre " + liquid + ".");
              }
          }

      现在你可以象这样创建一个 mycup 对象: 

      var mycup = new Cup("white", 0.5, "china", "pink", "rose");

      该创建了 mycup 并且将指定的值赋给它的属性。因而 mycup.color 的值是字符串 "whhite", mycar.weight 的值是0.5(此处省略重量单位),依此类推。

      你可以通过调用 new 创建任意数量的 car 对象。例如:

      var lilicup = new Car("red", 0.4, "plastic", "blue", "girl"); 
      var raincup = new Car("grown", 0.4, "glass", "green", "tree");
    • 使用Object.create(ECMAScript5及之后支持)

      对象也可以用 Object.create 方法创建。该方法非常有用,因为它允许你为创建的对象选择其原型对象,而不用定义一个构造函数。

      Object.create(proto[, propertiesObject])

       proto是指所创建对象的原型对象,propertiesObject是一个对象值,可以包含若干个属性。

          var Cup = {
              color: "white", //default value of properties
              weight: 0.5,
              material: "china",
              design: {
                  color: "pink",
                  mark: "rose"
              },
              fill: function (liquid, volumn) {
                  //todo
                  console.log("The " + this.color +  " and " + this.material +  " cup is filled with " + volumn + " litre " + liquid + ".");
              }
          }
          //create new cup type called mycup
          var mycup = Object.create(Cup);
          mycup.fill("water", 0.2); //output: The white and china cup is filled with 0.2 litre water.
      
          var lilycup = Object.create(Cup);
          lilycup.color = "red";
          lilycup.material = "plastic";
          lilycup.fill("apple juice", 0.3); //Output: The red and plastic cup is filled with 0.3 litre apple juice.
  4. 如何使用对象?

    当构建好一个对象后,我们就可以访问对象的属性和方法:

    objectName.propertyName
    objectName.methodName();

     关于这个使用我们在上面sample里面已经使用过了,例如

    lilycup.material = "plastic";

    lilycup.fill("apple juice", 0.3); 

    从ECMAScript5开始Javascript有三种方法可以获取对象中所有的属性:

    • for...in

      依次获取一个对象及其原型的所有可列举的属性。

    • Object.keys(o)

      该方法返回对象 o 自身包含(不包括原型中)的所有属性的名称的数组。

    • Object.getOwnPropertyNames(o)

      该方法返回一个数组,它包含了对象 o 自身(不包括原型)拥有的属性(无论是否可枚举)的名称。

  5. 对象的修改

    从ECMAScript5开始Javascript可以通过getter和setter方式为对象实例定义属性:

        function Cup(color, weight, material, designColor, markImage) {
            this.color = color;
            this.weight = weight;
            this.material = material;
            this.design = { color: designColor, mark: markImage };
            this.fill = function (liquid, volumn) {
                //todo
                console.log("The " + this.color + "  and " + this.material + " cup is filled with" + volumn + " litre " + liquid + ".");
            }
        }
        Object.defineProperty(Cup.prototype, 'description', {
            get: function () {
                return "It is a " + this.color + " cup!";
            },
            set: function (description) {
                var iStart = description.indexOf("It is a ");
                var iEnd = description.indexOf(" cup!");
                if (iStart != 0 || iEnd < 0 || iStart >= iEnd) {
                    throw "Invalid description, please descript it in the format: It is a [color] cup!";
                }
                this.color = description.substring(8, iEnd);
            }
        });
    
        var myCup = new Cup("red");
        console.log(myCup.description); // It is a red cup!
        myCup.description = "It is a blue cup!";
        console.log(myCup.color); // blue
    Object.defineProperty语法如下
    Object.defineProperty(obj, prop, descriptor)

     Obj为需要定义属性的对象,prop为需要定义或者修改的属性名, descriptor为需被定义或修改的属性的描述符。

    对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。描述符必须是两种形式之一;不能同时是两者。

    数据描述符和存取描述符均具有以下可选键值:

    • configurable, 当且仅当这个属性描述符值为 true 时,该属性可能会改变,也可能会被从相应的对象删除。默认为 false。
    • enumerable, 为true时表示该属性可以被枚举出,现在相应的对象枚举属性中。默认为 false。

    数据描述符同时具有以下可选键值:

    • value, 与属性相关的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
    • writable, 为true时表示可以用赋值运算符改变与属性相关的值。默认为 false。

    存取描述符同时具有以下可选键值:

    • get, 定义获取属性值的方法,如果没有 getter 则为 undefined。默认为 undefined。
    • set, 定义给属性赋值的方法。

    属性也可以从对象中删除

    delete expression

    你可以使用 delete 操作符来删除一个隐式声明的全局变量,也就是没有使用 var 定义的全局变量.全局变量其实是global对象(window)的属性。一些对象的属性不能被delete. ECMA 262 规范中把这些属性标记为 DontDelete。

        x = 42;        // the implicit global variable(can be removed)
        var y = 43;    // the explicit global variable(cannot be removed)
        myobj = new Number();
        myobj.h = 4;    // can be removed
        myobj.k = 5;    // can be removed
    
        delete x;       // return true(remove successfully)
        delete y;       // return false (fail to remove,该属性有DontDelete标记)
        delete Math.PI; // return false (内置对象的内置属性不能被删除, 该属性有DontDelete标记)
        delete myobj.h; // successfully remove
        delete myobj;   // successfully remove

    你不能删除一个对象从原型继承而来的属性(不过你可以从原型上直接删掉它)。

    function Foo(){}
     Foo.prototype.bar = 42;
     var foo = new Foo();
     delete foo.bar;           
     alert(foo.bar);           // 42
     delete Foo.prototype.bar; // delete it from the prototype Object
     alert(foo.bar);           // undefined

     

关于对象的继承以及对象的几个主要方法我们将在下一篇文章里介绍。

你可能感兴趣的:(JavaScript)