javascript对象

    xiaoxiao2021-03-26  26

    6.0 对象

    __proto__和prototype的关系:https://www.zhihu.com/question/34183746/answer/58068402

    对象是一种复合值:它将很多值聚合在一起,可通过名字访问这些值。

    对象的常见用法:创建、设置、查找、删除、检测和枚举它的属性。

    属性特性:可写(是否可以设置该属性的值),可枚举(是否可通过for/in返回该属性),可配置(是否可以删除或修改该属性)。

    三类js对象和两类属性的区分:

    内置对象(是由ECMAScript规范定义的对象或类。例如数组、函数、日期、正则)

    宿主对象(宿主环境定义的对象,比如HTMLElement)

    自定义对象(运行js代码创建的对象)

    自有属性(直接在对象中定义的属性)

    继承属性(在对象的原型对象中定义的属性)

    6.1 创建对象

    创建对象的三种方式:

    对象直接量:var obj={ x:1,y:2 };访问方式:obj.x或obj["x"]

    new运算符创建并初始化一个新对象:var a=new Date();

    object.create函数创建的对象:var c=object.create( {} )或var c=object.create(null);

    6.1.3 原型

    对象通过原型的继承方式形成了一种"原型链"形式,可继承原型链上的原型对象的属性和方法,也可以动态创建原型对象(prototype)的属性和方法

    每个js对象(null除外)都有和另一个对象相关联。“另一个”对象就是我们熟知的原型,每个对象都从原型继承属性

    Object.prototype没有原型对象

    属性prototype就是原型对象,不过由于是隐型的,所有大多浏览器都给出了__proto__ 作为构造该对象的原型对象

    比如:对象直接量 var a1={ x:1,y:2 }; a1.__proto__指向原型对象object.prototype

        通过new构造函数 function f(){}; var a2=new f(); a2.__proto__==f.prototype;

        函数f的原型对象 f.prototype,函数f的原型对象的原型对象 f.prototype.__proto__指向 Object.prototype

    6.1.4 Object.create()

    ECS5定义了Object.create()方法,它创建一个新对象,其中第一个参数是这个对象的原型。

    比如:var o1=Object.create( { x:1,y:2 } );

    6.2 属性的查询和设置

    6.2.1 作为关联数组的对象

    object.property

    object["property"]

    6.2.2 继承

    javascript对象使用某个属性时会查找原型链上的所有可能存在的属性

    原型继承方式 object.prototype=其他原型对象

    6.2.3 属性访问错误

    只读属性会报错;继承的只读属性,同名自有属性会报错;可扩展性是false会报错

    6.3 删除属性

    delete运算符可以删除对象的属性,只能删除自有属性,不能删除继承属性,可删除可配置属性(可修改)

    6.4 检测属性

    检测一个对象是否有指定属性的方式:

    in运算符 : var o={ x:1 }; "x" in o ;=>true;也可以检测继承属性

    只能检测自有属性:obj.hasOwnProperty(属性) 

    只能检测自有属性且可枚举的属性:obj.propertyIsEnumerable(属性)

    获取指定对象的原型对象: Object.getPrototypeOf(普通对象);

    6.5 枚举属性

    for/in;Object.getOwnPropertyNames();Object.keys()

    6.6 属性getter和setter

    区别于数据属性,getter和setter定义了存取器属性。

    var p={ x:1.0,y:1.0, get r(){ return this.x*5+this.y*5; }, set r(newvalue){ this.x=newvalue; this.y=newvalue; }, };

    6.7 属性的特性

    除了包含名字和值之外,属性还包含一些标志它们 可写、可枚举和可配置的特性。

    开发库的作用:可以通过这些API给原型对象添加方法,并将它们设置成不可枚举的,折让它们看起来更像内置对象。

        可以通过这些API给对象定义不能修改或删除的属性,借此“锁定”这个对象。

    数据属性:包含 值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)

    存取器属性: 包含 读取(get属性代替)、写入(set属性代替)、可枚举性(enumerable)和可配置性(configurable)

    ECS5定义了 “属性描述符”的对象,这个对象代表上述4个特性

    Object.getOwnpropertyDescriptor() 可以获得某个对象特定自有属性的属性描述符,比如:

    object.getOwnpropertyDescriptor( {x:1},"x" );  => { value:1, writable:true, enumerable:true, configurable: true }

    Object.defineProperty(要修改的对象,要创建或修改的属性的名称,属性描述符对象),Object.defineProperties(多属性的属性描述符修改),比如:

    var o={};

    Object.defineProperty( o,"x",{ value:1,writable:true, enumerable: false, configurable: true } );

    属性是存在的,但不可枚举o.x =>1;Object.keys(o)  => []

    var p=Object.defineProperty({},

    { x:{ value: 1,writable:true,enumerable: true,configurable: true,y:{ value:2,writable:true,enumerable:true,configurable:true } } }

    );

    常见错误类型:

    a.如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给它添加新属性;

    b.如果属性是不可配置的,则不能修改它的可配置性和可枚举性;

    c.如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将它转换为数据属性;

    d.如果数据属性是不可配置的,则不能将它转换为存取器属性;

    e.如果数据属性是不可配置的,则不能将它的可写性从false修改为true,但可以从true修改为false; 

    f.如果数据属性是不可配置且不可写的,则不能修改它的值。然而可配置但不可写属性的值是可以修改的(实际是先标记为可写,再修改值,最后转换为不可写)

    6.8 对象的三个属性

    每个对象都有与之相关的原型(prototype)、类(class)和可扩展性(extensible attribute)。

    6.8.1 原型属性

    var p={ x:1 };

    var o=Object.create(p);

    p.isPrototypeOf(o); =>true:o继承自p

    Object.prototype.isPrototypeOf(o); =>true:p继承自Object.prototype

    6.8.2 类属性

    可通过 toString获得类属性

    function classof(){

    if( o==null ){ return "Null"; }

    if( o==undefined ){ return "Undefined" };

    return Object.prototype.toString.call(o).slice(8,-1);

    }

    classof(1) => "Number"

    6.8.3 可扩展性

    Object.esExtensible():判断该对象是否是可扩展的

    Object.preventExtensions:将待转换的对象作为参数传进去,转换为不可扩展的(自有属性)

    Object.seal() :可将对象设置为不可扩展,还可以将对象的所有自有属性都设置为不可配置的

    Object.freeze():“冻结”,可设置对象为不可扩展和其自有属性设置为不可配置之外,还可以将它自有的所有数据属性设置为只读

    Object.isFrozen():检测对象是否冻结

    6.8.9 序列化对象

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

    ECS5提供了内置函数JSON.stringify()和JSON.parse()用来序列化和还原JavaScript对象。这些方法都使用JSON作为数据交换格式。

    转载请注明原文地址: https://ju.6miu.com/read-350345.html

    最新回复(0)