JS对象及其属性描述

数据类型

ECMAScript 规定变量值可以分为两种类型的数据:一个是基本类型值(原始值),一个是引用类型值(引用值)。基本类型值有六种:String、Number、 Boolean、Undefined、Null和 Symbol(ES6)。引用类型值只有一种,就是是由多个值构成的对象。 

什么是对象

对象是无序的属性和方法的集合,对象它被认为是某个特定引用类型的实例,在 ECMAScript 中,引用类型是一种数据结构,它描述了某类对象所具有的属性和方法,(因此引用类型也可以理解为对象的类型/分类)。虽然引用类型有点像类,但跟类并不是一个概念。

常用的引用类型有Object、Array、Date、Function、RegExp、Error、Boolean、Number、String。我们可以通过new操作符+构造函数来创建某一类型的对象,构造函数就是用来创建对象的函数,比如 new + Date 就创建了一个日期对象,同理有数组对象,函数对象,正则对象,布尔对象,数字对象,字符串对象,错误对象等等。

因此在JS中,除了六个基本类型值外,其他全都是对象。

ECMAScript引用类型的区分(对象的类型的区分)

引用类型有Object、Array、Date、Function、RegExp、Error、Boolean、Number、String,他们大部分是构造函数,由于函数也是对象,因此这些引用类型也是对象了。

有两种引用类型比较特殊,分别是基本包装类型和单体内置对象。

基本包装类型(原始值包装类型)

为了便于操作基本类型值,ECMAScript 还提供了 3 个特殊的引用类型:Boolean、Number 和 String。每当用到某个基本类型值的方法或属性时,都会自动创建一个相应基本包装类型的实例,从而可以调用该实例的各种属性和方法。

单体内置对象

前面的引用类型多是构造函数,但是单体内置对象是已经实例化了,可直接使用。ECMAScript定义了几个单体内置对象,有Global 和 Math 和 JSON。

JS对象的分类

(前面是ECMAScript引用类型的分类,这个是JS对象的分类。)JS对象可以分为内置对象、宿主对象和自定义对象。

内置对象

内置对象的定义:任何由 ECMAScript实现提供、与宿主环境无关,并在代码开始执行时就存在的对象。这就意味着,开发者不用显式地实例化内置对象,因为它们已经实例化好了。比如Object、Array等虽然是构造函数,但也是Function的实例,所以也是函数对象,而且他们身上有很多方法可直接使用。

例如:Object、Array、Date、Function、RegExp、Error、EvalError 、RangeError 、ReferenceError 、SyntaxError 、TypeError、URIError 、Boolean、Number、String、Global、Math、JSON都属于内置对象。

宿主对象

由宿主提供的对象就是宿主对象,宿主就是JS运行环境,JS可以在浏览器中运行,也可以在node服务器上运行,那么浏览器就是宿主。所以浏览器提供的对象就是宿主对象。例如:window、location、history、screen、navigator、document都是宿主对象,所有的DOMBOM对象都属于宿主对象。

自定义对象

开发人员自己定义的对象。

属性名注意点

一个对象里面,他的属性名只有两种情况,一种是字符串,一种是符号symbol(了解),如果你给的属性名不是字符串,那他会转成字符串,如obj[10 ]实际上属性名是 '10',只是js并没有用引号包裹起来而已。

        let obj = {};
        obj[10] = 1;
        obj['10'] = 11;
        obj[{}] = '对象'
        console.log(obj)
结果:  {
        10: 11,
        [object Object]: "对象"
       }

属性的特性

JS有一些内部特性用来描述属性的特征,分别是

  1. Enumerable:是否可枚举(是否可被Object.keys()或者for..in遍历出来)---共有
  2. Configurable:是否可被delete删除,是否可修改特性 ---共有
  3. Writable:属性值是否可被修改 ---数据属性独有
  4. Value:存放属性值,默认值为 undefined  ---数据属性独有
  5. Get:获取函数,读取属性调用 ---访问器属性独有
  6. Set:设置函数,写入属性调用  ---访问器属性独有

属性的类型

根据内部特性,可以将属性分为数据属性和访问器属性。显式的给对象添加属性,并且几个特性都是true。使用Object.defineProperty添加属性,不指定特性则默认都是false或者undefined。

要修改属性的默认特性,就必须使用 Object.defineProperty() 方法。这个方法接收 3 个参数:
要给其添加属性的对象、属性名和一个描述符对象,描述符对象包括上面六个特性,数据属性和访问器属性各四个,Writable、value和Get、Set不能同时存在。有Writable和Value就为数据属性,有Get和Set为访问器属性。

        let obj = { age: 26 };   //显式添加属性
        Object.defineProperty(obj, 'name', { value: 'zjh', writable: true });
        console.log(Object.getOwnPropertyDescriptor(obj, 'age'));
        console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
        console.log(Object.keys(obj));
//显式添加
{
    "value": 26,
    "writable": true,       //默认都是true
    "enumerable": true,
    "configurable": true
}
//Object.defineProperty
{
    "value": "zjh",
    "writable": true,
    "enumerable": false,   // 默认都是false
    "configurable": false
}
//name不会被遍历出来
[
    "age"
]

访问器属性的典型使用场景,就是设置属性值可以使其他属性发生变化。

(访问器属性仅了解,具体需要可看书)

        let obj = { age: 26 };
        let num = 100;
        Object.defineProperty(obj, 'score', {
            get() {
                console.log('get');
                return num;  //直接拿外部的num当返回值,也就是修改num,score也变了
            },
            set(n) {
                console.log('set');
                num = n;
            }
        })
        obj.score       //调用get
        obj.score = 90;   //调用set

        // 核心: Object.defineProperty创建的访问器属性让外面的变量num和对象产生了关系
        // 调用getter,实际就是拿num返回给score,调用setter,实际上就是修改num

可枚举属性的遍历方法

for...in... 和 Object.keys() 都只能遍历可枚举属性,他们的区别在于 for..in..还能遍历原型链上的可枚举属性。

        let person = {
            name: '周嘉宏',
            sex: '男',
        }
        Object.defineProperty(person, 'age', {
            value: 18,
        })
        person.__proto__.type = '人类';
        for (key in person) {
            console.log(key);   // 'name' 'sex'  'type'
        }
        console.log(Object.keys(person));  // ['name', 'sex']
       
        for..in..和 object.keys 都不能遍历出 age 这个不可枚举属性.
        
        同样,Object.values 也只能遍历可枚举属性的值
        console.log(Object.values(person));  // ['周嘉宏', '男']

不可枚举属性的遍历方法

Object.getOwnPropertyNames可以遍历出不可枚举属性

        let person = {
            name: '周嘉宏',
            sex: '男',
        }
        Object.defineProperty(person, 'age', {
            value: 18,
        })
        person.__proto__.type = '人类';
        console.log(Object.values(person));   ['name', 'sex']
        console.log(Object.getOwnPropertyNames(person));  ['name', 'sex', 'age']

只有  for..in..能遍历原型链上的可枚举属性。只有Object.getOwnPropertyNames可以遍历自身的不可枚举属性。

属性简写

当属性值是一个变量的时候,并且和属性名相同的时候,就可以使用属性简写形式

        let name = 'zjh';
        let obj = {
            name: name   
        }
        let obj1 = {
            name
        }
        console.log(obj);
        console.log(obj1);

下面这中情况不能使用简写形式,属性值不是变量的时候

        let obj = {
            name1: 'name1'   //虽然属性值是字符串name1,但他不是变量
        }
        let obj1 = {
            name1        //报错,引用错误name1
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值