zoukankan      html  css  js  c++  java
  • JS: The Definitive Guide 笔记 Object

    JavaScript里最基本的数据类型是对象。
    JavaScript里的对象其实是一个无序的属性集合,属性又是一个个的名-值对。
     
    除了字符串,数字,true,false,null或者undefined以外,其他所有的值在JavaScript里头都是对象。
     
    对象是引用类型,如果变量x表示一个对象,当执行var y = x;语句后,实际上y和x指向的是同一个对象。所以,当你通过y改变对象的值,这种变化也会反映到x上。
     
     
    如何创建对象:
    1. 字面量表示法:
    var book = {};   //创建一个没有属性的对象
    var book = {
       name : "The Definitive Guide",
       "main title" : "JavaScript",      //当属性名中间有空格,或者“-”时,要用引号把属性名括起来
       author : {                          //对象的属性也可以是对象
          firstname : "Rex",
          lastname : "Mai
       }
    };    

    2. 使用new关键字:

    var o = new Object(); // 创建一个空对象,效果等同{}.
    var a = new Array(); // 创建一个空数组,效果等同 [].
    var d = new Date(); // 创建一个表示当前时间的对象
    var r = new RegExp("js"); // 创建一个正则表达式对象

    3. 使用Object.create() ,这是ECMAScript5 新添加的方法,该方法接受一个参数——对象原型。

    var o1 = Object.create({x:1, y:2});
    var o2 = Object.create(Object.prototype); // 结果等同于{}或new Object()

    你可以给该方法传null,结果会是一个不继承任何属性和方法的空对象

    获取对象的值

    通过.或者[]操作符。

    book.title;
    book["title"];
    
    var propertyName = "title";
    book[propertyName];

    如果对象的属性是固定的,那么这两个方法的作用差别不大。但由于javascript是一种松散类型的语言,所以,你可以在程序运行期间为对象添加任意数量的属性。当你使用.操作符访问对象属性时,.后面的名字其实只是一个标识符,所以你必须完整的输入这个标识符,才能够访问到。

    属性特性:

    在ECMAScript5中,添加了API同获取和设置属性特性。在这里,我们有一个对象,property descriptor,它用来表示属性的4个特性(value/get, writable/set, enumerable, configurable)。其中,writable, enumerable和configurable属性为布尔值,get和set属性为function。

    我们可以通过Object.getOwnPropertyDescriptor()获取特定对象里某个属性的property descriptor,这个方法只能获取对象的自有属性。

    // Returns {value: 1, writable:true, enumerable:true, configurable:true}
    Object.getOwnPropertyDescriptor({x:1}, "x");
    // Now query the octet property of the random object defined above. // Returns { get: /*func*/, set:undefined, enumerable:true, configurable:true} Object.getOwnPropertyDescriptor(random, "octet");
    // Returns undefined for inherited properties and properties that don't exist. Object.getOwnPropertyDescriptor({}, "x"); // undefined, no such prop Object.getOwnPropertyDescriptor({}, "toString"); // undefined, inherited

    通过Object.defineProperty()来设置属性特性,该方法有3个参数,1.操作的对象,2.要修改或创建的属性名,3.property descriptor对象

    var o = {}; // Start with no properties at all
    // Add a nonenumerable data property x with value 1.
    Object.defineProperty(o, "x", { value : 1,
                        writable: true,
                        enumerable: false,
                        configurable: true});
    // Check that the property is there but is nonenumerable
    o.x; // => 1
    Object.keys(o) // => []
    // Now modify the property x so that it is read-only
    Object.defineProperty(o, "x", { writable: false });

    传入的property descriptor对象不需要把4个特性全部包含进去;如果是创建新属性,特性又没有出现在property descriptor对象里,则那些特性值为false或者undefined。如果是修改属性,没出现的特性值不会改变。该方法只会创建或修改自有对象,不会改变改变继承的属性。

    应该也注意到了,Object.defineProperty()只能创建或设置一个属性,如果想一次性创建或修改多个属性,可以使用Object.defineProperties(),它有2个参数,1.要修改的对象,2.包含属性名及property descriptor对象的对象

    var p = Object.defineProperties({}, {
      x: { value: 1, writable: true, enumerable:true, configurable:true },
      y: { value: 1, writable: true, enumerable:true, configurable:true },
      r: {
      get: function() { return Math.sqrt(this.x*this.x + this.y*this.y) },
         enumerable:true,
         configurable:true
    }
    });

    对象属性:

    原型属性(prototype):对象的原型属性石用来继承属性的。

    通过直接量创建的对象,原型为:Object.prototype
    通过new创建的对象,原型为:构造函数的prototype
    通过Object.create()创建的对象,原型为:使用的第一个参数

    ECMAScript5中,将对象作为参数传入Object.getPrototypeOf(),可以获取对象的原型。

    通过对象直接量或Object.create()创建的对象包含一个名为constructor的属性,该属性指代Object()构造函数。

    想要检测一个对象是否是另一个对象的原型(或出于原型链中),可以使用isPrototypeOf()方法。

    p.isPrototypeOf(o)         //若o是p的原型或存在于原型链中,则返回true

    类属性(class):对象的类属性是一个字符串,用以表示对象类型信息。ECMAScript3和5都没有提供设置这个属性的方法,而且只有一个间接的方法可以查询它——默认的toString()方法。但由于很多对象继承的toString()方法被重写了,所以最好使用call去调用。

    function classof(o) {             //该函数可以返回传递给它的任意对象的类
      if( o === "null" ) return "Null";
      if( o === "undefined") return "Undefined";
      Object.prototype.toString.call(o).slice(8,-1);
    } 

     内置构造函数创建的对象包含“类属性”,它与构造函数名称相匹配。通过对象直接量,Object.create()和自定义构造函数创建的对象的类属性是“Object”,创建的对象也是一样,类属性也是“Object”。因此对于自定义的类来说,没办法通过类属性来区分对象的类。

    classof(null) // => "Null"
    classof(1) // => "Number"
    classof("") // => "String"
    classof(false) // => "Boolean"
    classof({}) // => "Object"
    classof([]) // => "Array"
    classof(/./) // => "Regexp"
    classof(new Date()) // => "Date"
    classof(window) // => "Window" (a client-side host object)
    function f() {}; // Define a custom constructor
    classof(new f()); // => "Object"

    可扩展属性(extensible):该属性用以表示是否可以给一个对象添加新属性。在ECMAScript5中,所有内置对象和自定义对象都是显示可扩展。

    Object.esExtensible():用来判断对象是否是可扩展的。
    Object.preventExtensions():用来将对象转换为不可扩展。注意,一旦将对象设为不可扩展,则无法再将其转换回可扩展。该方法也只会影响到对象本身的可扩展性。如果给一个不可扩展的对象的原型添加属性,这个不可扩展对象还是会继承这些新属性。
    Object.seal():和preventExtensions()类似,它除了可以将对象设备不可扩展外,还可以将对象的所有自有属性设置为不可配置的。也就是说,不可以给这个对象添加新属性,而且它的已有属性也不能删除或者配置,但是它的已有可写属性依然可以设置。被封闭(seal)的对象,是不能解锁(unseal)的。我们可以通过Object.isSeal()方法来检测对象是否封闭。
    Object.freeze():更严格的锁定对象。和seal类似,不过它还会将自有的所有数据属性设为只读(如果对象的存储器有setter方法,该属性不会被影响,也就是说可以通过给属性赋值调用它们)。通过Object.isFrozen()检测对象是否冻结。

    对象方法:

    toString(),toLocaleString(),toJSON(),valueOf()

  • 相关阅读:
    2016年3月至9月随笔
    带大三个hybird app项目的设计管理笔记
    小议新人的培养
    GitHub上整理的一些工具,求补充——转的,先mark了
    AutoMapper(一)——实现数据契约和实体类之间的转换
    GitHub上整理的一些工具
    我最常用的7个Web在线工具
    在线团队协作工具+在线UML工具
    轻量级SaaS在线作图工具(继之前介绍后完整介绍)
    分享自己使用的在线UML画图工具
  • 原文地址:https://www.cnblogs.com/rexmzk/p/2815112.html
Copyright © 2011-2022 走看看