当前位置: 首页 > news >正文

JavaScript高级程序设计读书分享之8章——8.1理解对象

JavaScript高级程序设计(第4版)读书分享笔记记录

适用于刚入门前端的同志

  •  创建自定义对象的通常方式是创建 Object 的一个新实例,然后再给它添加属性和方法。
let person = new Object()
person.name = 'Tom'
person.age = 18
person.sayName = function(){//示 this.name 的值,这个属性会解析为 person.name。console.log(this.name) // Tom  
}

以上代码就创建了一个名为person的对象,有两个属性(name,age)和一个方法(sayName)。

  • 使用对象字面量创建对象
let person = {name:'Tom',age:18,sayName(){console.log(this.name) //Tom}
}

属性的类型

属性分两种:数据属性访问器属性

数据属性

数据属性有 4个特性描述它们的行为:
  •  [[Configurable]]:表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为访问器属性。默认情况下,这个特性都是 true
  •  [[Enumerable]]:表示属性是否可以通过 for-in 循环返回。默认情况下,这个特性都是 true。
  •  [[Writable]]:表示属性的值是否可以被修改。默认情况下,这个特性都是 true。
  • [[Value]]:包含属性实际的值。这就是前面提到的那个读取和写入属性值的位置。这个特性的默认值为 undefined
要修改属性的默认特性,就必须使用 Object.defineProperty()方法。
这个方法接收 3 个参数:1.要给其添加属性的对象、2.属性的名称和一个描述符对象。最后一个参数,即描述符对象上的属性可以包含:configurableenumerablewritable value,跟相关特性的名称一一对应。
例如:
let person = {}
Object.defineProperty(person,'name',{writable:false,configurable:false,value:'Tom'
})console.log(person.name) // Tom//这里修改person对象的name值,是无效的,因为上面writable:false,就说明属性的值不可被修改
person.name = 'Jerry'
console.log(person.name) // Tom//这里删除person对象的name属性,是删除不了的因为上面configurable:false,就说明该属性不能被delete
delete person.name
console.log(person.name) // Tom

注意

  • 在调用 Object.defineProperty()时,configurableenumerable writable 的值如果不指定,则都默认为 false
  • 此外,一个属性被定义为不可配置之后(false),就不能再变回不能再变回可配置的了再次调用 Object.defineProperty()并修改任何非 writable 属性会导致错误
  • 在不支持 Object.defineProperty()的浏览器中没有办法修改[[Configurable]][[Enumerable]]

访问器属性

访问器属性有 4 个特性描述它们的行为
  • [[Configurable]]:表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为数据属性。默认情况下,所有直接定义在对象上的属性的这个特性都是 true
  •  [[Enumerable]]:表示属性是否可以通过 for-in 循环返回。默认情况下,所有直接定义在对象上的属性的这个特性都是 true
  • [[Get]]获取函数,在读取属性时调用。默认值为 undefined
  • [[Set]]:设置函数,在写入属性时调用。默认值为 undefined

访问器属性是不能直接定义的,必须使用 Object.defineProperty()

例子:

// 定义一个对象,包含伪私有成员 year_和公共成员 edition 
let book = { year_: 2017, edition: 1
}Object.defineProperty(book ,"year",{get(){return this.year_},set(newVal){if(newVal > 2017){this.year_ = newValthis.edition += newVal - 2017}}
})console.log(book.year) // 2017book.year = 2018
console.log(book.year) // 2018
console.log(book.edition) // 2

定义多个属性

ECMAScript 提供Object.defineProperties()方法。这个方法可以通过多个描述符一次性定义多个属性。
它接收两个参数:1.要为之添加或修改属性的对象,2.另一个描述符对象,其属性与要添加或修改的属性一一对应

let book = {}; 
Object.defineProperties(book, { year_: { value: 2017 ,// writable:true}, edition: { value: 1 ,// writable:true}, year: { get(){ return this.year_; },set(newValue){console.log("1112222222222",newValue)if (newValue > 2017) { this.year_ = newValue; console.log("1112222222222" ,this.year_)this.edition += newValue - 2017; }}}
})
console.log(book.year_) // 2017
console.log(book.year) // 2017
console.log(book.edition) // 1//此时这里修改了year 的值 但是打印没变
book.year = 2018console.log(book.year_) // 2017
console.log(book.year) // 2017
console.log(book.edition) // 1

注意:

唯一的区别是所有属性都是同时定义的,并且数据属性的configurable、enumerable writable 特性值都是 false。!!!
所以上面修改了year还是没变,就要把writable改为true

let book = {}; 
Object.defineProperties(book, { year_: { value: 2017 ,writable:true}, edition: { value: 1 ,writable:true}, year: { get(){ return this.year_; },set(newValue){console.log("1112222222222",newValue)if (newValue > 2017) { this.year_ = newValue; console.log("1112222222222" ,this.year_)this.edition += newValue - 2017; }}}
})
console.log(book.year_) // 2017
console.log(book.year) // 2017
console.log(book.edition) // 1book.year = 2018console.log(book.year_) // 2018
console.log(book.year) // 2018
console.log(book.edition) // 1

读取属性的特性

使用 Object.getOwnPropertyDescriptor()方法可以取得指定属性的属性描述符。这个方法接收两个参数:属性所在的对象和要取得其描述符的属性名。返回值是一个对象

接上面的book例子:

let descriptor = Object.getOwnPropertyDescriptor(book, "year_"); 
console.log(descriptor.value); // 2017 
console.log(descriptor.configurable); // false 
console.log(typeof descriptor.get); // "undefined" let descriptor = Object.getOwnPropertyDescriptor(book, "year"); 
console.log(descriptor.value); // undefined 
console.log(descriptor.enumerable); // false 
console.log(typeof descriptor.get); // "function"

ECMAScript 2017 新增了 Object.getOwnPropertyDescriptors()静态方法,返回值是一个对象

接上面的book例子:

let descript =  Object.getOwnPropertyDescriptors(book)
console.log(descript )

打印值:

合并对象

ECMAScript 6 专门为合并对象提供了 Object.assign()方法
  • 这个方法接收一个目标对象和一个或多个源对象作为参数。
  • 注意:Object.assign()的属性拷贝是浅拷贝
  • 同名属性替换,如果多个源对象都有相同的属性,则使用最后一个复制的值。
示例:
let dest ,src, result;//一个源对象
dest = {}
src = {id:'src'}result = Object.assign(dest,src)
console.log(result ) // {id:'src'}//多个源对象
dest = {}
result = Object.assign(dest, { a: 'foo' }, { b: 'bar' }); 
console.log(result); // { a: foo, b: bar }// 浅复制体现
dest = {} 
src = { a:{b:1}}result  = Object.assign(dest ,src)
console.log(result) // { a:{b:2}} 因为是浅复制,值指向同一位置
console.log(result.a.b) // 1 
src.a.b = 2
console.log(result.a.b) // 2//覆盖属性
dest = {id:'dest'}
result  = Object.assign(dest ,{id:'src',a:1},{id:'test',b:2})
console.log(result  ) // {id:'test',a:1,b:2}

对象标识及相等判定

ECMAScript 6 规范新增了 Object.is()
  • 这个方法与===很像,用来比较两个值是否严格相等。
  • 这个方法必须接收两个参数
Object.is("q","q");      // true
Object.is(1,1);          // true
Object.is([1],[1]);      // false
Object.is({q:1},{q:1});  // false

与 === 的区别

//一是+0不等于-0
console.log( Object.is(+0,-0) );  //false
console.log( +0 === -0 )   //true
//二是NaN等于本身
console.log ( Object.is(NaN,NaN) ); //true
console.log (NaN === NaN)  //false

增强的对象语法

ECMAScript 6 为定义和操作对象新增了很多极其有用的语法糖特性

属性简写

ES6允许对象的属性直接写变量,这时候属性名是变量名,属性值是变量值。

const age = 12;
const name = "Amy";
const person = {age, name};
console.log(person) //{age: 12, name: "Amy"}
//等同于
const person = {age: age, name: name}

可计算属性

有了可计算属性,就可以在对象字面量中完成动态属性赋值
const nameKey = 'name'; 
const ageKey = 'age'; 
const jobKey = 'job'; 
let person = { [nameKey]: 'Matt', [ageKey]: 27, [jobKey]: 'Software engineer' 
}; 
console.log(person); // { name: 'Matt', age: 27, job: 'Software engineer' }

简写方法名

const person = {sayHi(){console.log("Hi");}
}
person.sayHi();  //"Hi"//等同于
const person = {sayHi:function(){console.log("Hi");}
}
person.sayHi();//"Hi"

对象解构

ECMAScript 6 新增了对象解构语法,可以在一条语句中使用嵌套数据实现一个或多个赋值操作
// 使用对象解构
let person = { name: 'Matt', age: 27 
}; 
let { name: personName, age: personAge } = person; 
console.log(personName); // Matt 
console.log(personAge); // 27
让变量直接使用属性的名称,那么可以使用简写语法。
let person = { name: 'Matt', age: 27 
}; 
let { name, age } = person; 
console.log(name); // Matt 
console.log(age); // 27
        解构并不要求变量必须在解构表达式中声明。不过,如果是给事先声明的变量赋值,则赋值表达式必须包含在一对括号中:
let personName, personAge; 
let person = { name: 'Matt', age: 27 
}; 
({name: personName, age: personAge} = person); 
console.log(personName, personAge); // Matt, 27

相关文章:

JavaScript高级程序设计读书分享之8章——8.1理解对象

JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 创建自定义对象的通常方式是创建 Object 的一个新实例,然后再给它添加属性和方法。 let person new Object() person.name Tom person.age 18 person.sayName function(){//示 this.name…...

代码随想录算法训练营第四十天 | 343. 整数拆分,96.不同的二叉搜索树

一、参考资料整数拆分https://programmercarl.com/0343.%E6%95%B4%E6%95%B0%E6%8B%86%E5%88%86.html 视频讲解:https://www.bilibili.com/video/BV1Mg411q7YJ不同的二叉搜索树https://programmercarl.com/0096.%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BA%8C%E5%8F%89%E6%90…...

数据结构与算法系列之顺序表的实现

这里写目录标题顺序表的优缺点:注意事项test.c(动态顺序表)SeqList.hSeqList.c各接口函数功能详解void SLInit(SL* ps);//定义void SLDestory(SL* ps);void SLPrint(SL* ps);void SLPushBack(SL* ps ,SLDataType * x );void SLPopBack(SL* ps…...

基于Linux_ARM板的驱动烧写及连接、挂载详细过程(附带驱动程序)

文章目录前言一、搭建nfs服务二、ARM板的硬件连接三、putty连接四、挂载共享文件夹五、烧写驱动程序六、驱动程序示例前言 本文操作环境:Ubuntu14.04、GEC6818 这里为似懂非懂的朋友简单叙述该文章的具体操作由来,我们的主要目的是将写好的驱动程序烧进…...

python-爬虫-字体加密

直接点 某8网 https://*****.b*b.h*****y*8*.com/ 具体网址格式就是这样的但是为了安全起见,我就这样打码了. 抛出问题 我们看到这个号码是在页面上正常显示的 F12 又是这样就比较麻烦,不能直接获取.用requests库也是获取不到正常想要的 源码的,因为字体加密了. 查看页面源代码…...

计算机组成原理4小时速成5:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线

计算机组成原理4小时速成5:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人&#xff0c…...

安全狗受聘成为福州网信办网络安全技术支撑单位

近日,福州市委网信办召开了2022年度网络安全技术支撑单位总结表彰大会。 作为国内云原生安全领导厂商,安全狗也出席了此次活动。 据悉,会议主要对2022年度优秀支撑单位进行表彰,并为2023年度支撑单位举行授牌仪式。 本次遴选工…...

RV1126 在Ubuntu18.04开发环境搭建

1:安装软件终端下输入安装命名:sudo apt install openssh-serversudo apt install android-tools-adbsudo apt install vim net-tools gitsudo apt install cmakesudo apt install treesudo apt install minicomsudo apt install gawksudo apt install bisonsudo ap…...

如何在 C++ 中调用 python 解析器来执行 python 代码(一)?

实现 Python UDF 中的一步就是学习如何在 C 语言中调用 python 解析器。本文根据 Python 官方文档做了一次实验,记录如下: 1. 安装依赖包 $sudo yum install python3-devel.x86_642. 使用 python-config 来生成编译选项 $python3.6-config --cflags -…...

操作系统权限提升(二十三)之Linux提权-通配符(ws)提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 操作系统权限提升(十九)之Linux提权-SUID提权 操作系统权限提升(二十)之Linux提权-计划任务提权 操作系统权限提升(二十一)之Linux提权-环境变量劫持提权 操作系统权限提升(二十二)之Linux提权-SUDO滥用提权 利用通配符…...

Zookeeper下载和安装

Zookeeper 1.下载 官方下载地址:https://zookeeper.apache.org/ 版本:apache-zookeeper-3.7.1-bin.tar.gz 2. 安装 2.1 本地安装 2.1.1 安装JDK 见:Hadoop集群搭建 2.1.2 上传安装包 使用远程工具拷贝安装包到Linux指定路径 /opt/s…...

Biomod2 (上):物种分布模型预备知识总结

Biomod11.栅格数据处理1.1 读取一个栅格图片1.2 计算数据间的相关系数1.3 生成多波段的栅格图像1.4 修改变量名称1.4.1 计算多个变量之间的相关性2. 矢量数据处理2.1 提取矢量数据2.2 数据掩膜2.2 栅格计算2.3 拓展插件的使用3. 图表绘制3.1 遥感影像绘制3.2 柱状图分析图绘制3…...

操作指南:如何高效使用Facebook Messenger销售(二)

上一篇文章我们介绍了使用Facebook Messenger作为销售渠道的定义、好处及注意事项,本节我们将详细介绍怎么将Facebook Messenger销售与SaleSmartly(ss客服)结合,实现一站式管理多主页配图来源:SaleSmartly(…...

计算机三级|网络技术|中小型网络系统总体规划与设计方案|IP地址规划技术|2|3

p3 p4一、中小型网络系统总体规划与设计方案网络关键的设备选型路由器技术指标性能指标综述吞吐量背板能力丢包率时延抖动突发处理能力路由表容量服务质量网管能力可靠性和可用性1 吞吐量指路由器的包转发能力,涉及两个内容:端口吞吐量和整机吞吐量&…...

为什么一定要做集成测试?

集成测试,我们都不陌生,几乎我们产品每天都在进行。但是我们真的有好好思考:为什么一定要做集成测试吗?只是为了简单的将“积木”搭起来就行,还是有什么其他的深意? 深意可能不一定会有,但是意…...

前端:CSS

CSS基本语法规则:选择器若干属性声明 style标签:可以放到代码的任意位置处,head/body中都可以 三种写CSS的方式: 1、内部样式:使用style标签,直接把CSS写到html文件中。此时的style标签可以放到任何位置…...

CMMI—组织级过程定义(OPD)

大家好,我是Doker 多克!一、目的组织级过程定义(Organizational Process Definition, OPD)的目的在于建立并维护一套可用的组织级过程资产、工作环境标准以及团队规则与指南二、简介组织级过程资产使得整个组织具有一致…...

华为OD机试真题Python实现【猜字谜】真题+解题思路+代码(20222023)

猜字谜 题目 小王设计了一个简单的猜字谜游戏,游戏的谜面是一个错误的单词,比如nesw,玩家需要猜出谜底库中正确的单词。 猜中的要求如下: 对于某个谜面和谜底单词,满足下面任一条件都表示猜中: 变换顺序以后一样的,比如通过变换w和e的顺序,nwes跟news是可以完全对应的…...

软测入门(三)Selenium(Web自动化测试基础)

Selenium(Web端自动测试) Selenium是一个用于Web应用程序测试的工具:中文是硒 开源跨平台:linux、windows、mac核心:可以在多个浏览器上进行自动化测试多语言 Selenium WebDriver控制原理 Selenium Client Library…...

备战蓝桥杯——sort函数

备战蓝桥杯——sort函数排列字母lambda匿名函数排列字母 链接: 排列字母 不用多说,很简单的签到题,我们先来了解一下sort函数的用法 list.sort(cmpNone, keyNone, reverseFalse) cmp:进行比较的方法(可以自定义排序的方法,通常…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

数据库分批入库

今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...