zoukankan      html  css  js  c++  java
  • 6.JavaScript对象

    对象

    JavaScript中的对象是由键值对组成,每个键值对可以称为属性,静态数据属性包括名字和四个特性,存取器属性则略有不同,对象本身也有三个属性,分别是原型属性,类属性以及可拓展属性,Object.prototype中存有一些可供所有对象使用的方法,如toString(),valueOf()等

    对象是JavaScript的基本数据类型,对象可以看成是属性的无序集合,每个属性都是一个键值对,属性名通常是字符串,因此我们可以对象看成是从字符串到值的映射.然而对象不仅仅是字符串到值的映射,还可以从一个称为原型的对象继承属性.

    对象的属性包括名字和值,属性名可以是包含空字符串在内的任意字符串,但属性名不能同名,值可以是JavaScript任意值,或者是getter和setter函数.

    每个属性还有一些与之相关的值,称为属性特性(这些特性是可以加以配置的):

    • 可写,表明是否可以设置该属性的值
    • 可枚举,表明是否可以通过for/in循环返回该属性
    • 可配置,表明是否可以删除或修改属性

    除了包含属性之外,每个对象还有相关的对象特性:

    • 对象的原型指向另一个对象,本对象的属性继承自它的原型对象
    • 对象的类是一个标识对象类型的字符串
    • 对象的拓展标记指明了是否可以向该对象添加新属性

    创建对象

    1.直接使用对象直接量

    对象直接量是由若干键值对组成的映射表,键值对中间使用冒号,每对键值对用逗号分隔,整个映射表用花括号括起来.

    对象直接量是一个表达式,表达式每次运算都创建并初始化一个新的对象

    var empty = {};
    var point = {
    x:0,
    y:1
    };
    

    2.通过new创建对象

    new运算符创建并初始化一个新对象.关键字new后跟随一个函数调用,这个函数称为构造函数(constructor),构造函数用以初始化一个新创建的对象.

    var o = new Object();
    var a = new Array();
    var b = new Date();
    var c = new RegExp("js")
    

    3.原型

    每一个除null外的对象都与另一个对象相关联,另一个对象就叫做原型.

    所有通过对象直接量创建的对象都具有同一个原型对象,并可以通过Object.prototype获得原型对象的引用.通过关键字new创建的对象的原型就是构造函数的prototype属性的值,所以,通过new Object()创造的对象原型就是Object.prototype,数组的就是Array.prototype,日期的就是Date.prototype.

    Object.prototype是没有原型的,Date等构造函数都有继承自Object.prototype的原型,如Date.prototype的属性继承自Object.prototype

    4.Object.create()

    Object.create()将创建一个新对象,第一个参数是这个对象的原型,第二个参数用以对对象的属性进行进一步描述

    可以用Object.create(Object.prototype)来创建一个新的空对象

    function inherit(p){
    if(p===null) throw TypeError();
    var t = typeof p;
    if(t!=='object' && t!=='function') throw TypeError();
    function f(){};
    f.prototype = p;
    return new f();
    }
    

    属性的查询和设置

    var name = author.name;
    var name = author["name"]
    

    以上两种方法进行查询,也可直接设置属性

    第二种方式看起来更像数组,但索引变成了字符串索引,这种数组就是所说的关联数组,也叫散列,映射或字典,JavaScript对象都是关联数组.

    假如要查找一个对象的属性,如果当前对象不存在,则会在对象的原型对象中查询,还不存在就接着往上查询直到找到这个属性或者查找到一个原型是null的对象为止

    在JavaScript中,只有查询才会体会到继承的存在,而设置属性与继承无关

    属性的删除

    delete运算符可以删除对象的属性,但delete不可以删除那些可配置性为false的属性(比如变量声明和函数声明的全局函数)

    o = {x:1};
    delete o.x;//删除成功
    delete o.x;//不存在,什么也不做 返回true
    delete o.toString;//同上
    

    检测属性

    判断某个属性是否存在于某个对象中,可以通过in运算符、hasOwnProperty()和propertyIsEnumerable()方法实现.

    var o = {x:1};
    "x" in o;  //ture
    "y" in o;  //false
    "toString" in o //true,继承
    

    hasOwnProperty()用于检测给定的名字是否是对象的自有属性.但对于继承属性返回false

    var o = {x:1};
    o.hasOwnProperty("x"); //true
    o.hasOwnProperty("y"); //false
    o.hasOwnProperty("toString")  //false
    

    propertyIsEnumerable()相当于hasOwnProperty()的增强版,它只检测是自由属性请可枚举的的属性

    除了这些方法还可以用!来判断,比如o.x ! undefined

    枚举属性

    之前提到的for/in循环遍历对象中所有可枚举的属性(包括自有属性和继承属性),把属性名称赋值给循环变量.所有为了避免继承的影响,通常会这样

    for(p in o){
    if(!o.hasOwnProperty(p)) continue;  //跳过继承的属性
    }
    
    for(p in o){
    if(typeof o[p] === "function") continue //跳过方法
    }
    

    此外还有Object.keys(),它返回一个数组,这个数组由可枚举的自有属性的名称组成,还有一个枚举属性的函数是Object.hasOwnPropertyNames(),它和上一个函数类似,但它返回对象的所有自有属性的名称

    setter和getter

    对象的属性值可以有一两个方法替代,这两个方法就是getter和setter,由这两个方法定义的属性就是"存取器属性"

    var o = {
        data_prop: value,//普通属性
        get accessor_prop(){},
        set accessor_prop(value){}
    }
    

    属性的特性

    属性除了包含名字和值外,还包含一些可写,可枚举,可配置的特性.一般可以把数据属性看成是一个名字和四个特性,数据属性的四个特性是它的,可写性,可枚举性可配置性.存取器属性不具有值特性和可写性,它的可写性由setter存在与否决定,因此存取器属性的四个特性是读取,写入,可枚举,可配置.

    通过调用Object.getOwnPropertyDescriptor()可以获得某个对象特定属性的属性描述符

    Object.getOwnPropertyDescriptor({x:1},"x")
    //返回 {value:1,writable:true,enumerable:true,configurable:true}
    Object.getOwnPropertyDescriptor(random,"octet")
    //返回 {setter:undefined,getter:/*func*/,enumerable:true,configurable:true}
    Object.getOwnPropertyDescriptor({},"x")
    //不存在,返回undefined
    

    如果想要设置属性特性,或想让新建属性具有某特性,则要调用Object.defineProperty(),传入要修改的对象,要创建或修改的属性的名称以及属性描述符对象

    var o = {};
    Object.defineProperty(o,"x",{
        value: 1,
        writable: true,
        enumerable: false,//不可枚举
        configurable: true
    })
    o.x; //1
    Object.keys(o); //[]不可枚举
    Object.defineProperty(o,"x",{writable: false})//无法修改值
    Object.defineProperty(o,"x",{get: function(){return 0}})
    //将x从数据属性修改成存取器属性
    o.x; //0
    

    对象的三个属性

    原型属性

    对象的原型属性是用来继承属性的,简称为原型.原型属性是在实例对象创建之初就设置好的,

    通过对象直接量创建的对象使用Object.prototype做为原型,通过new函数创建的对象则用构造函数的prototype属性作为原型,前两项其实都是构造函数constructor属性的prototype作为原型,Object.create()使用传入的参数作为原型

    想检测一个对象是否是另一个对象的原型可以用isPrototypeOf()或者instanceOf()方法检测

    类属性

    对象的类属性是一个字符串,用以表示对象的类型信息.

    通过内置构造函数创建的对象包含类属性(class attribute),它与构造函数名称相匹配,通过对象直接量和Object.create()传教的对象的类属性是object,自定义构造函数创建的对象类属性也是object

    可拓展性

    对象的可拓展性用以表示是否可以给对象添加新属性.所有内置对象和自定义对象都是显式可拓展的,宿主对象的可拓展性由JavaScript引擎定义.

    通过将对象传入Object.esExtensible()来判断对象是否可拓展,如果想将对象转换成不可拓展,需要调用Object.preventExtensions()

    Object.seal()将对象设置为不可拓展并且把所有自有属性设置为不可配置,可用Object.isSealed()来检测对象是否封闭

    Object.freeze()将对象冻结,除了设置不可拓展和属性设置不可配置外,还将自有的所有数据属性设置为只读,使用Object.isFrozen()判断是否冻结

    序列化对象

    对象序列化是指将对象的状态转换成字符串,也可将字符串还原为对象

    可以使用JSON.stringfy()和JSON.parse()来序列化和还原对象.

     o = {x:1,y:{z:[false,null,""]}};
     s = JSON.stringify(o);//转换成字符串 '{"x":1,"y":{"z":[false,null,""]}}'
     p = JSON.parse(s);//p是o的深拷贝
    

    JSON(JavaScript object notation)JavaScript对象表示法,JSON的语法是JavaScript语法的子集,支持对象,数组,字符串,无穷大数字,布尔值和null,并且可以序列化和还原,NaN,infinity的序列化结果是null,日期对象序列化是ISO格式的日期字符串,但JSON.parse()并不会还原成原始日期对象,函数,RegExp,Error对象undefined值不能序列化和还原

    对象方法

    • toString()

      该方法没有参数,它返回一个表示调用这个方法的对象值的字符串.在需要变成字符串的时候,JavaScript会调用这个方法,比如+

    • toLocaleString()

    ​ 除了基本的toString()外,对象都包含toLocaleString()方法,这个方法返回一个表示这个对象的本地化字符串,object中默认的toLocaleString()不返回任何本地化自身的操作,仅调用自身的toString(),Date和Number类对toLocalString()方法做了定制,可以用它对数字,日期和时间进行本地化转换.数组调用则会让每个数组元素调用toLocalString()方法转换成字符串

    • toJSON()

    ​ 对于需要执行序列化的对象来说,JSON.stringify()方法会调用toJSON()方法.

    • valueOf()

    ​ 该方法和toString()方法很像,但往往当JavaScript需要将对象转换为某种原始值而非字符串才会调用它,尤其是转换为数字,如果在需要使用原始值的上下文中使用了对象,JavaScript就会自动调用这个方法

  • 相关阅读:
    cull/clip distance example
    Sutherland-Hodgeman多边形裁剪
    OpenCV 脸部跟踪(3)
    人脸识别中的Procruster analysis应用
    卡尔曼滤波的原理说明
    偏导数
    泊松分布E(X^2)
    抽奖概率
    卡尔曼滤波的原理说明
    卡尔曼滤波3
  • 原文地址:https://www.cnblogs.com/dwfeng/p/13804984.html
Copyright © 2011-2022 走看看