【基本系列】javascript中的对象

此次我们好好聊一聊对象这个东西,本次说的不是
array,也不是
function,而是
object

基本观点

对象是一种特别的数据类型,这类数据类型另有其他的许多叫法,比方“散列”,“散列表”,“字典”,“关联数组”。

对象依据建立者的角度,能够分为三类:
内置对象:是由javascript言语自身自定义的对象,大多数是一些预定好的组织函数类,比方ArrayDateFunction
宿主对象:是指javascript诠释器所嵌入的宿主环境定义的对象,比方HTMLElement就是宿主对象。
自定义对象:是指由开发者在代码中所建立的对象。

我们晓得对象的表达体式格局是:‘属性’:’值’

属性依据泉源差别,能够分为两类:
自有属性:是指直接在对象中定义的属性。
继续属性:是指在对象原型链中的属性。

与此同时,对象的属性还具有一些特征:
可写:代表是不是能够设置该对象所对应的该属性的值。
可罗列:代表是不是能够经由过程api罗列出该属性。
可设置:代表是不是能够删除或修正该属性。

记着上述观点,有助于我们举行下一步的明白。

建立对象

建立对象有三种体式格局:
第一种:对象直接量

var o = {}
var obj = {
    a: 1,
    'b': 2,
    'min title': 3
}

第二种:经由过程new建立对象

var o = new Object()

第三种:Object.create()
该要领支撑传入两个参数,第一个参数是对象的原型(就是所建立出的对象的_proto_的指向),第二个参数是对属性进一步的形貌(该参数可选,参数内容会在背面详解

《【基本系列】javascript中的对象》

以下三种体式格局是等价的:
《【基本系列】javascript中的对象》

检测对象原型的要领除了instanceof以外,另有一个isPrototypeOf(),我们来看一下运用:

《【基本系列】javascript中的对象》

对象的getter和setter

我们起首再明白一个观点:
我们罕见的{a: 1}中的a叫做数据属性,除此以外另有一个叫做存取器属性,存取器属性的值的读取和设置,都是由getter和setter掌握的。

var o = {
    p: 0,
    set q(value) {
        this.p = value
    },
    get q() {
        return this.p+=100
    }
}
o.q = 1
console.log(o.q)    // => 101
console.log(o.q)    // => 201

个中,对象中的函数定义没有运用function关键字,运用的而是getset关键字

处置惩罚能够如许定义存取器属性,我们还能够应用其他的要领定义存取器属性,就是我们熟知的Object.defineProperty()Object.definePeoperties()

起首,我们引见一下Object.defineProperty()定义数据属性的体式格局

var o = {}
// 定义属性
Object.defineProperty(
    o, 
    'x', 
    {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: true
    }
)
// 修正属性
Object.defineProperty(
    o, 
    'x', 
    {
        value: 2,
        writable: false
    }
)

这个函数共有三个参数:
第一个参数是,须要加属性的对象。

第二个参数是,增添的属性的称号。

第三个参数是定义的设置项:
第一个设置就是这个属性所对应的值。
盈余三个设置就是对应到文章一开始所提到属性三个特征可写可罗列可设置
这四个设置项都不是必需填写。假如关于新建立的属性,value不填,默许值就是undefined,其他设置项的缺省值是false。假如关于修正已有的属性来讲,不填写的设置项就不做修正。

我们再看一下Object.defineProperty()定义存取器属性的体式格局
个中,须要注重的是,在定义存取器属性时没法定义,valuewritable设置项,由于定义的getset从某种意义上替代了前两个设置项。

var o = {y: 1}
Object.defineProperty(
    o, 
    'x', 
    {
        set(value) {
            this.y = value
        },
        get() {
            return this.y+=100
        },
        enumerable: true,
        configurable: true
    }
)

Object.defineProperty只能单个定义或修正对象属性,Object.defineProperties供应了批量处理的方法,以下:

var o = {}
Object.defineProperties(
    o,  
    {
        x: {
            set(value) {
                this.y = value
            },
            get() {
                return this.y+=100
            },
            enumerable: true,
            configurable: true
        },
        y: {
            value: 1,
            writable: false,
            enumerable: true,
            configurable: true
        }
    }
)

Object.definePropertyObject.defineProperties关于属性的修正是有划定规矩和请求的,以下:

  1. 假如对象是不可扩大的,则能够编辑已有的自有属性,但不能给它增添新属性。
  2. 假如属性是不可设置的,则不能修正它的可设置性和可罗列性。
  3. 假如存取器属性是不可设置的,则不能修正其getter和setter要领,也不能将它转换为数据属性。
  4. 假如数据属性是不可设置的,则不能将它转换为存取器属性。
  5. 假如数据属性是不可设置的,则不能将它的可写性从false修正为true,但能够从true修正为false。
  6. 假如数据属性是不可设置且不可写的,则不能修正它的值。但是可设置但不可写属性的值是能够修正的(实际上是先将它标记为可写的,然后修正它的值,末了转换为不可写的)。

在这里,我们再看一下上面的Object.create要领,Object.create的第二个参数是和Object.defineProperties第二个参数一样的,缺省值一样为undefinedfalse

没有供应选项去设置属性特征的要领,这些属性默许都是true,比方:new关键字和对象直接量的体式格局建立对象,以及最上面对象直接量的体式格局设置getter和setter

对象的扩大性

对象的扩大性是什么,实在就是指对象可否增添新的属性,默许情况下一切的内置对象和自定义对象都是可扩大的。除非我们工资的转变它:

Object.preventExtesions()能够传入一个参数,就是你要作废扩大功用的对象,操纵后,这个对象会不能扩大(即不能增添新属性),且不能恢复,操纵只影响该对象自身,不对其他原型链操纵产生影响。
我们能够应用Object.esExtensible()推断这个对象是不是可扩大,传入一个对象,返回布尔值。

Object.seal()能够将对象关闭,结果和上面的Object.preventExtesions()一样,增添的结果是将这个对象的自有属性设置为不可设置(行将configurable设为false),一样不能解封。
我们能够应用Object.isSealed()来推断这个对象是不是关闭,传入一个对象,返回布尔值。

Object.freeze()能够将对象冰冻,结果和上面的Object.seal()一样,增添的结果是将这个对象的自有属性设置为不可写(行将writable设为false),一样不能冻结。
Object.isFrozen()能够推断这个对象是不是冰冻。

依据属性查询值

依据属性查询值的体式格局我们固然是尽人皆知了,[].,固然他们也能够设置和修正可写性为true的自有属性值

var o = {}
Object.defineProperties(
    o,  
    {
        x: {
            value: 1,
            writable: true,
            enumerable: true,
            configurable: true
        },
        y: {
            value: 1,
            writable: false,
            enumerable: true,
            configurable: true
        }
    }
)

o.x    // => 1
o['x'] = 5
o.x    // => 5
o.y = 5
o.y    // => 1

删除属性

delete能够用户删除对象属性,能删除的属性只是该对象的自有属性属性设置性为true的属性

让人觉得不测的是,delete只是断开属性和宿主对象的联络,而不会去操纵属性中的属性。

《【基本系列】javascript中的对象》

检测属性是不是存在

检测属性共有三种体式格局,in操纵符,hasOwnPropertypropertyIsEnumerable

in能够检测对象的自有属性继续属性,不受属性特征的影响

var o = {x: 1}
'x' in o    // true
'y' in o    // false
'toString' in o    // true

hasOwnProperty只能检测对象的自有属性,不能检测继续属性,不受属性特征的影响

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

propertyIsEnumerable只能检测自有属性,且请求这个属性的可罗列性为true

罗列悉数属性

起首第一个要领是for/in,这个要领能够罗列出当前对象可罗列(属性罗列性为true)的自有属性和继续属性

var o = Object.create({z: 1})

Object.defineProperties(
    o,  
    {
        x: {
            value: 1,
            writable: true,
            enumerable: true,
            configurable: true
        },
        y: {
            value: 1,
            writable: false,
            enumerable: false,
            configurable: true
        }
    }
)

for (p in o) {console.log(p)}    // => x, z

第二个要领是Object.keys(),这个要领能够罗列出当前对象的可罗列(属性罗列性为true)的自有属性,返回值是一个数组

var o = Object.create({z: 1})

Object.defineProperties(
    o,  
    {
        x: {
            value: 1,
            writable: true,
            enumerable: true,
            configurable: true
        },
        y: {
            value: 1,
            writable: false,
            enumerable: false,
            configurable: true
        }
    }
)

Object.keys(o)    // => ['x']

第三个要领是Object.getOwnPropertyNames,它能够罗列出当前对象一切的自有属性(不受罗列性影响)

Object.defineProperties(
    o,  
    {
        x: {
            value: 1,
            writable: true,
            enumerable: true,
            configurable: true
        },
        y: {
            value: 1,
            writable: false,
            enumerable: false,
            configurable: true
        }
    }
)

Object.getOwnPropertyNames(o)    // => ['x', 'y']

对象的序列化和反序列化

JSON.stringify()JSON.parse()

    原文作者:bradwang
    原文地址: https://segmentfault.com/a/1190000013460102
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞