对象定义-解构-枚举属性遍历以及对象内函数

news2024/9/28 11:15:34

属性名表达式

定义对象的属性有两种方式
1、直接使用标识符作为属性名 obj.name
2、以表达式作为属性名 obj['a'+'b'] = 10

let obj = {}
obj.name = '孙悟空'  // 孙悟空
obj['a' + 'b'] = 10  // 10
console.log(obj); // {name: '孙悟空', ab: 10}

es5中字面量定义对象只能使用一种方法

var obj2 = {name:'东方',age:10}

es6允许使用表达式属性名,将表达式放入方括号内即可

let key = 'address'
let obj3 = {
     name:'不败',
     [key] : '武汉',
     ['a'+'ge'] : 100
   }
console.log(obj3);  // {name: '不败', address: '武汉', age: 100}
console.log(obj3.address);  // 武汉
console.log(obj3[key]);  // 武汉

表达式还可以定义方法名

let obj4 = {
      ['f'+'n'](){
      console.log('hello');
         },
     fn2 : function(){ console.log('word') }
   }
obj4.fn() // hello
obj4.fn2()  // word

注意:解构与属性名表达式不能同时使用

// 报错
let fan = 'name'
let tion = { [fan] }

属性名表达式如果是对象,会被转换成字符串[object object]

let o = {a : 1}
let o2 = {b : 2}

let obj5 = {
      [o] : '东方不败',
      [o2] : '西方求败'
   }
console.log(obj5);   // {[object Object]: '西方求败'}

由于属性名表达式都被转换为[object Object],同键名的会被覆盖,所以这里只输出最后一个{[object Object]: '西方求败'}


name属性

函数的name属性返回函数名,对象方法也是函数,因此也有name属性

let n = {
    sayHi(){console.log('hello');}
   }
console.log(n.sayHi.name);   // sayHi

如果对象的方法使用了取值函数:getter或存值函数setter,那么的属性在描述对象的getset身上,需要在方法名前假getset

let n2 = {
      get fn(){},
      set fn(x){}
   }
let desc = Object.getOwnPropertyDescriptor(n2,'fn')
console.log(desc.get.name);  // get fn
console.log(desc.set.name);  // set fn
console.log(n2.fn.name);  // 报错 Cannot read properties of undefined (reading 'name')

如果对象的方法是一个Symbol值,name属性返回的是Symbol值的描述

let key1 = Symbol('desc')
let key2 = Symbol()
let kobj = {
     [key1](){},
     [key2](){}
  }
console.log(kobj[key1].name);  // [desc]
console.log(kobj[key2].name);  // ""

key1有描述,返回描述[desc]key2没有值,返回空


属性的可枚举性和遍历

对象的每个属性都存在一个描述对象,用来控制该属性的行为
获取属性描述对象的方法:Object.getOwnPropertyDescriptor()

let d = { a : 123 }
console.log(Object.getOwnPropertyDescriptor(d,'a'));
//{value: 123, writable: true, enumerable: true, configurable: true}

在这里插入图片描述
其中,enumerable 为枚举属性,true为可枚举,false为不可枚举
下面四个操作会忽略enumerablefalse属性
1、for...in循环:只遍历对象自身的和继承的可枚举属性
2、Object.keys():返回对象自身的所有可枚举的属性的键名
3、JSON.stringify():只串行化对象自身的可枚举属性
4、Object.assign():忽略enumerablefalse的属性,只拷贝对象自身的可枚举属性。

其中for...in会返回继承的属性,其它的几个都会忽略继承的属性
如果枚举属性为false,这四个方法遍历时会忽略为false的属性


对象遍历方法

方法说明
for…in循环遍历对象自身和继承的可枚举属性(不含Symbol)
Object.keys返回一个数组,该数组为对象自身的所有可枚举属性(不含继承属性和Symbol属性)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有(包含不可枚举)属性(不含Symbol属性)
Object.getOwnPropertySymbols返回一个数组,只包含对象自身的所有Symbol属性的键名
Reflect.ownKeys返回一个数组,包含对象自身的(不含继承)所有键名,(含Symbol、字符串、不可枚举属性)

下面是这些遍历方法的演示
定义对象

 let s = Symbol('sym')  // Symbol类型
 let f = {a:1, b:2, c:3, d:4, e:5, [s]:6}

for…in

for (k in f) {
    // 键名
    console.log(k);  // a b c d e
    // 属性
    console.log(f[k]); // 1 2 3 4 5
}

Object.keys返回对象键名数组

console.log(Object.keys(f));  // ['a', 'b', 'c', 'd', 'e']
Object.keys(f).forEach(el => console.log(el))  // a b c d e

Object.getOwnPropertyNames

console.log(Object.getOwnPropertyNames(f));  // ['a', 'b', 'c', 'd', 'e']

Object.getOwnPropertySymbols

console.log(Object.getOwnPropertySymbols(f));  // [Symbol(sym)]

Reflect.ownKeys

console.log(Reflect.ownKeys(f));  // ['a', 'b', 'c', 'd', 'e', Symbol(sym)]

注意:Symbol是不可枚举的

 let desc2 = Object.getOwnPropertyDescriptor(f,s)
 console.log(desc2); // {value: 6, writable: true, enumerable: true, configurable: true}
 // 在这里返回的是enumerable:true,返回的是对象的枚举属性,并不是Symbol
 // Symbol是不可枚举的,所以keys遍历中没有Symbol

解构赋值和剩余运算符

解构:可以根据对象的键名直接获取到键值,非常方便

let { a,b,...z } = { a:1, b:2, c:3, d:4, e:5 }
console.log(a,b,z);  // 1 2 {c: 3, d: 4, e: 5}
let info = {
    id:1,
    name:'东方不败'
 }
let {id ,name} = info
console.log(id,name);  // 1 '东方不败'

解构赋值可以嵌套

  • 单层嵌套
  let infos = {
    vals : 1,
    users: {
        names : '东方不败'
    }
  }
  let {vals ,users:{names} } = infos
  console.log(names);  // 东方不败
  • 多层嵌套
  let info2 = {
    val:1,
    user:{
        id2:100,
        name2:'东方不败',
        address:{
            city:'武汉',
            district : '世界城广场'
        }
    }
  }
  let { val,user:{id2,name2,address:{city,district}} } = info2
  console.log(val,id2,name2,city,district);  // 1 100 '东方不败' '武汉' '世界城广场'

对象的剩余运算符可以将字符串转换成键值对的对象,键名默认从数字0开始,依次排列

console.log({...'world'});  // {0: 'w', 1: 'o', 2: 'r', 3: 'l', 4: 'd'}

对象的剩余运算符相当于是Object.assign(),但这两个是不相等

let r = { id : 1, name:'东方', text:'不败'}
let res = {...r}
let res2 = Object.assign({},r)
console.log(res);  // {id: 1, name: '东方', text: '不败'}
console.log(res2); // {id: 1, name: '东方', text: '不败'}
console.log(res == res2);  // false

剩余运算符拼接,重复的键名会被覆盖

let r2 = { a:1 , b:2 , c:3 , d:4}
let r3 = {c:6,d:7,e:8,f:9}
console.log({...r2,...r3});  // {a: 1, b: 2, c: 6, d: 7, e: 8,f: 9}

对象内函数

对象内不仅可以定义普通的数据类型如:字符串、数字、数组,还可以定义函数,对象内函数的行为跟普通函数相同,普通函数和箭头函数在对象内都可以定义,函数的调用方式:对象名.方法

let fn = {
   title:'东方不败',
   sayHi(){console.log('hello')},
   getSum(x){return x % 2 == 0 ? true : false},
   getNum : s = (x) => x + 1
}

console.log(fn.title); // 东方不败
fn.sayHi()  // hello
console.log(fn.getSum(3)); // false
console.log(fn.getSum(4)); // true
console.log(fn.getNum(1)); // 2

Object.keys()可以遍历对象键名数组,对象内的函数会返回函数名

Object.keys(fn).forEach(el=> console.log(el))  // title sayHi getSum getNum

对象内函数的this

对象内函数的this指向问题跟普通函数有一些不同

对象内函数:
普通函数:this指向的是对象本身,也就是当前对象内的所有属性和方法。
箭头函数:this指向为window,因为对象不构成单独的作用域,导致箭头函数定义时的作用域是全局作用域。

window.val = '西方求败'
let fn2 = {
    name : '艺术概论',
    inThis(){ console.log(this.val)},  // 普通函数
    inThis2(){ 
        console.log(this.name)
        console.log(this);
     },  // 普通函数
     inThis3 : t = () => {
        console.log(this.val)
        console.log(this);
        const t2 = () => {
            console.log(this);
        }
    }  // 箭头函数
}

// 普通函数
function getThis2(){
   console.log(this.val);
 }
 getThis2()  // 西方求败
 fn2.inThis()  // undefined
 fn2.inThis2() // 艺术概论  // {name: '艺术概论', inThis: ƒ, inThis2: ƒ}
 fn2.inThis3() // 西方求败  // Window {window: Window, self: Window, document: document, name: '', location: Location, …}

这里分别在对象内定义了普通函数箭头函数
inThis()输出的是undefined,因为对象内并没有val这个属性,this.val没有找到,返回undefined
inThis2()输出的是艺术概论this.name就是当前对象内的name,对象内的普通函数this指向的是当前对象
inThis3()为箭头函数,输出西方求败,对象内的箭头函数this指向的是window


案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果觉得这篇文章对你有帮助,欢迎点亮一下star哟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/129289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.3.3、划分子网的 IPv4 地址

若有一个大型的局域网需要连接到因特网 若需要申请一个 C 类网络地址,其可分配的 IP 地址数量只有 254254254 个,不够使用 因此申请了一个 B 类网络地址,其可分配的 IP 地址数量达到了 655346553465534 个 给每台计算机和路由器的接口分配一…

实验九、消除互补输出级交越失真方法的研究

一、题目 互补输出级交越失真消除方法的研究。 二、仿真电路 基本互补电路和消除交越失真互补输出级如图1所示。晶体管采用 NPN 型晶体管 2N3904 和 PNP 型晶体管 2N3906。二极管采用 1N4009。 在实际的实验中,几乎不可能得到具有理想对称性的 NPN 型和 PNP 型管…

网络编程套接字----UDP协议

文章目录前言一、理解源IP地址和目的IP地址二、认识端口号理解"端口号"和"进程ID"理解源端口号和目的端口号三、认识TCP协议四、认识UDP协议五、网络字节序六、socket编程接口socket常见APIsockaddr结构sockaddr结构sockaddr_in 结构in_addr结构七、地址转…

第三方软件测试▏有效保障软件产品质量的关键性步骤

软件测试作为软件产品生命周期中不可或缺的重要步骤,被许多软件企业所重视。主要是通过对软件产品进行全面的测试,确保软件质量以及满足用户需求。但软件测试不仅仅是个简单的检测工作,而是一个系统性的、有组织性的测试过程,包含…

Linux:安装 telnet 命令

我是 ABin-阿斌:写一生代码,创一世佳话,筑一览芳华。如果小伙伴们觉得不错就一键三连吧~ 声明:原文地址:https://www.pudn.com/news/6332b44a272bb74d44053074.html 其他参考文章:https://www.cnblogs.com…

尚医通-上传医院接口-需求准备(十七)

目录: (1)数据接口-上传医院接口-需求准备 (1)数据接口-上传医院接口-需求准备 在医院接口设置的时候说过,我们做的是预约挂号平台,里面有数据的显示,挂号等等相关业务,…

计算机组成原理【by王道考研计算机】

文章目录第一章1. 什么是计算机系统2. 硬件的发展3. 计算机硬件的基本组成冯诺依曼结构现代计算机结构主存储器运算器控制器工作过程实例4. 计算机系统的层次结构五层结构三种级别的语言5. 计算机的性能指标存储器的容量CPU其他常用时间单位第二章1. 进制转换2. 字符与字符串3.…

下一代,容器工具Podman

一、简介 Kubernetes 团队发布了最新的 1.20 版本时,有一枚重磅炸弹:正式宣布弃用 Docker 支持的功能。弃用 Docker 之后,开发者们对其替代品的讨论逐渐热烈,其中 Containerd 和 Podman 倍受期待。 Podman 是一个开源的容器运行…

云原生、20.3k Star......时序数据库 TDengine 的 2022 年精彩纷呈

日月其迈,时盛岁新 2022 的进度条已经加载至“100%” 疫情肆虐下,毫无疑问 这仍然是头顶风雪攀登山峰的一年 好在如今曙光已现 回望这一年,TDengine 也硕果满满 2022 年是 TDengine 创立的第六个年头 我们付出着,也在收获着…

英伟达Orin芯片平台使用TensorRT加速部署YOLO

前言 自动驾驶行业想要在开发板上部署一套算法还是需要花费很大功夫的,因为计算资源的限制以及实时性要求高。并不像在服务器端部署算法那样粗犷。接下来就记录一下YOLO系列部署的过程,后期会把开发板上的问题都记录在此。 一、部署环境 计算平台&…

11.简单的CSS按钮悬停特效

效果 源码 <!DOCTYPE html> <html> <head><title>Button Hover Effects</title><link rel="stylesheet" type="text/css" href="style.css"> </head> <body><a href="#"><…

信贷产品年终总结之风控评分模型

叮咚&#xff0c;信贷年终总结的又一个专题来了&#xff0c;作为报告总结类的系列型文章&#xff0c;近期我们番茄知识星球平台陆续发布了相关年终总结专题&#xff0c;依次为客群特征画像、贷中行为分析、贷后逾期表现等&#xff0c;以上文章可详见之前陆续发布的内容。该业务…

nacos配置部署与管理

nacos配置部署与管理配置文件配置获取顺序&#xff1a;nacos配置热部署方式一&#xff1a;RefreshScope方式二&#xff1a;ConfigurationProperties配置文件 首先新建配置文件 Data ID&#xff1a;配置文件的名称&#xff08;唯一&#xff09;命名规范&#xff1a;服务名称-运…

广州车展|继原力技术之后,长安深蓝半固态电池呼之欲出

新年将至&#xff0c;万象更新。12月30日&#xff0c;2022第二十届广州国际汽车展览会在广州中国进出口商品交易会展馆隆重举办。全新数字纯电品牌长安深蓝携旗下首款战略车型深蓝SL03重磅参展&#xff0c;并邀请深蓝SL03车主亲临车展现场&#xff0c;或进行产品讲解&#xff0…

面向对象分析与设计的底层逻辑

作者&#xff1a;高福来 阿里全球化业务平台团队 在面向对象出现之前&#xff0c;已有面向过程的分析方法&#xff0c;那为什么面向对象被提出了呢&#xff1f;究其本质&#xff0c;人们发现面向过程并非按照人正常认识事物的方式去分析软件。面向过程是一种归纳的分析方法&a…

virtio技术(3)virtqueue机制

virtio技术&#xff08;3&#xff09;virtqueue机制 virtio的关键技术是virtqueue机制&#xff0c;其提供了一套统一的用于virito前端和后端的通信机制。virtqueue的核心数据结构是vring&#xff0c;这是virtio前端驱动和后端Hypervisor虚拟设备之间传输数据的载体。 vring数…

Word处理控件Aspose.Words功能演示:使用 Java 将 RTF 转换为 PDF

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…

改变podman的存储路径

使用podman容器时&#xff0c;podman会默认使用/var/lib/containers路径作为存储路径&#xff0c;可能会导致根磁盘空间占用过大&#xff0c;那如何修改podman的存储路径呢&#xff1f;本文将带你一起来探讨。 前几天公司的服务器根目录磁盘空间不足了&#xff0c;经过查找问题…

JAVA - fastjson 中 JSONObject 的顺序问题

目录 1. JSONObject 存在的默认排序问题一 1.1. 解决方案一 1.2. 解决方案二 2. JSONObject 存在的默认排序问题二 2.1. 解决方案一 2.2. 解决方案二 在使用 fastjson 中的 JSONObject 有时候会遇到数据顺序发生了变化&#xff0c;而实际需求中需要保持原有的顺序。 1…

【软件测试】测试人的巅峰?测试专家?

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 经常有人谈到&#…