• javascript基础知识-对象


    javascript创建对象有三种方法:

    1)对象直接量

    例:var empty = {};

        var point = {x:1,y:4};

        var book = {

           "main title":"JavaScript",

           'sub-title':"The Definitive Guide",

           "for":"audiences",

           author:{

               firstname:"David",

               surname:"Flanagan"

           }

        }

    2)通过new

    例:var o - new Object();

          var a = new Array();

          var d = new Date();

          var r = new RegExp("js");

    3)利用ECMAScript5中的Object.create()

    例:var o1 = Object.create({x:1,y:2});      //o1继承了属性x和y

          var o2 = Object.create(null);    //o2不继承任何属性和方法

          var o3 = Object.create(Object.prototype);   //o3和{}和new Object()一样

    可以通过任意原型创建新对象(换句话说,可以使任意对象可继承)

    下面的代码通过原型继承创建一个新的对象

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

    利用上面的代码,可以实现以下继承

    var o = {};
    o.x = 1;
    var p = inherit(o);
    p.y = 2;
    var q = inherit(p);
    q.z = 3;
    console.log(q.x + q.y);  //输出3

    另外,假设现在给对象o的属性x赋值,如果o中已经有了属性x(不是继承来的),那么这个赋值操作值改变这个已有属性x的值,如果o中不存在x属性,那么赋值操作给o添加一个x属性。如果之前o继承自属性x,那么这个继承属性就会被新创建的同名属性覆盖了。

    所以在javascript中,只有查询属性时,才会体会到继承的存在,而设置属性则与继承无关。(正是体现出了继承)

    属性赋值操作首先检查原型链,一次判断是否允许赋值操作。如果o继承自一个只读属性,那么赋值操作就是不允许的。

    var unitcircle = {r:1};
    var c = inherit(unitcircle);
    c.x = 1;c.y = 1;
    c.r = 2;
    console.log(unitcircle.r); //输出1
    console.log(c.r);  //输出2

    属性访问错误的问题

    当一个对象中某个属性不存在时,访问这个属性不会报错,只会报undefined。

    但是如果访问一个不存在的对象的属性,则会报一个错误 ReferenceError

    一种简练的常用方法,获取subtitle的length属性或者undefined

    var len = book && book.subtitle && book.subtitle.length;

    删除属性

    delete 运算符只能删除自有属性,不能删除继承属性。如果要删除继承属性,必须从定义这个属性的原型对象上删除它,这会影响到所有继承自这个原型的对象。

    另外delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性。

    比如

    var a = {p:{x:1}};
    var b = a.p;
    delete a.p;
    console.log(b.x);  //输出1

    属性getter和setter

    和数据属性不同,存取器属性不具有可读写性。如果属性同时具有getter和setter方法,那么它是一个读写属性。如果它只有getter方法,那么它是一个只读属性。如果它只有setter方法,那么它是一个只写属性(数据属性中有一些例外),读取只写属性总是返回undefined。

    下面是定义存取器属性最简单的方法:

    var o = {
        //普通数据属性
        data_prop:value,
    
        //存取器属性都是成对定义的函数
        get accessor_prop(){ /* 这里是函数体 */},
        set accessor_prop(value){/* 这里是函数体 */}
    };

    下面是一个关于私有属性的设定(带$符号的就是私有属性)

    var serialnum = {
        //这个数据属性包含下一个序列号
        //$符号暗示这个属性是一个私有属性
        $n:0,
    
        //返回当前值,然后自增
        get next(){ return this.$n++;},
        //给n设置新的值,但只有当它比当前值大时才设置成功
        set next(n){
            if(n >= this.$n)this.$n = n;
            else throw "序列号的值不能比当前值小";
        }
    };

    下面是利用getter来设置一个对象,用于返回0~255之间的随机数

    var random = {
       get octet(){return Math.floor(Math.random() * 255);},
       get unit16(){return Math.floor(Math.random() * 65536);},
       get int16(){return Math.floor(Math.random() * 65536) - 32768;}
    };

    属性的特性

    数据属性包含下面四个特性:值(value),可写性(writable),可枚举性(enumerable)和可配置性(configurable)

    存取器属性包含下面四个特性:读取(get),写入(set),可枚举性(enumerable)和可配置性(configurable)。

    下面是存取器属性的描述符对象:

    //返回{value:1, writable:true, enumerable:true, configurable:true}
    Object.getOwnPropertyDescriptor({x:1},"x");

    这些特性是可以设置的:

    var o = {};
    Object.defineProperty(o, "x", {
        value:1,
        writable:true,
        enumerable:false,
        configurable:true
    });
    o.x;  //返回1,不可枚举
    Object.keys(o)   //返回[]
    
    //现在对属性x做出修改,让它变成只读
    Object.defineProperty(o, "x", {writable:false});
    
    //尝试改变属性
    o.x = 2; //操作失败但不报错,而在严格模式中抛出类型错误异常
    o.x;
    
    //属性依然可配置,所以可以通过下面的方式进行修改
    Object.defineProperty(o, "x", {value:2});
    o.x;
    
    //现在将x从数据属性修改为存储器属性
    Object.defineProperty(o, "x", {get:function(){return 0;}});
    o.x; //返回0

    对象的三个属性

    1)原型属性

    原型属性是对象创建之初就设置好的

    创建对象的三种方法,对应原型属性的来源:

    ①通过对象直接量创建

    原型属性就是Object.prototype

    ②通过new创建的对象

    原型属性是使用构造函数的prototype属性

    ③通过Object.create()创建

    原型属性来自第一个参数(可以是null)

    在ECMAScript5中使用Object.getPrototypeOf来查询原型

    而在ECMAScript3中,则使用obj.constructor.prototype来检测一个对象的原型

    要检测一个对象是否是另一个对象的原型,可以使用isPrototypeOf()方法

    var p = {x:1};
    var o = Object.create(p);
    p.isPrototypeOf(o);                            //返回true
    Object.prototype.isPrototypeOf(o);   //返回true

    2)类属性

    可以通过下面的代码来获取类属性

    function classof(o){
        if(o===null)return "Null";
        if(o===undefined)return "Undefined";
        return Object.prototype.toString.call(o).slice(8,-1);
    }

    3)可扩展性

    对象的可扩展性用以表示是否可以给对象添加新属性

  • 相关阅读:
    函数
    向discuz里填充数据
    CI 基础
    FlashBuilder设置显示字符集
    win2003 Email邮件服务器搭配
    CI 模块化显示[仿照shopex功能]
    DW的鸟语
    CI 视图里加视图
    silverlight模拟单击事件
    自定义XML配置文件的操作类(转)
  • 原文地址:https://www.cnblogs.com/zjtTT/p/5008918.html
Copyright © 2020-2023  润新知