目录

1. 定义

1.1 创建对象

2.属性的类型

2.1 数据属性

2.2 修改默认属性

2.3 访问器属性

3.对象的操作

3.1 定义多个属性 Object.defineProperties( )

3.2 读取属性的特性

Object.getOwnPropertyDescriptor( )

Object.getOwnPropertyDescriptors( )

3.3 合并对象 Object.assign( )

4.增强的对象语法

4.1 属性值简写

4.2 可计算属性

5. 对象解构


1. 定义

ECMA-262 将对象定义为一组属性的无序集合,可以把对象想象成一张散列表。对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值。(也就是键值对)

1.1 创建对象

  • 通常方法

先创建一个 Object 实例,然后给它添加属性和方法(有点麻烦)

let person = new Object();
person.name = 'mike';
person.age = 18;
person.sayName = function() {console.log(this.name);
};
  • 对象字面量方法
let person = {name: 'mike',age: 18,sayName() {console.log(this.name);}// 也可以写成这样// sayName: function() {//     console.log(this.name);// }
};

2.属性的类型

属性包括两种

  • 数据属性
  • 访问器属性
特性的定义:ECMA-262 使用一些内部特性来描述属性的特征。这些特性是由为 JavaScript 实现引擎的规范定义 的。因此,开发者不能在 JavaScript 中直接访问这些特性。为了将某个特性标识为内部特性,规范会用两个中括号把特性的名称括起来,比如 [[ Enumerable ]]   。

2.1 数据属性

数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。数据属性有4个特性描述它们的行为。

  1. [[ configurable ]] : 表示属性是否可以通过 delete 删除并重新定义,是否可以修改他的特性。以及是否可以把它变成访问器属性。默认是 true
  2. [[ Enumerable]] : 表示属性是否可以通过 for-in 循环返回。默认是 true
  3. [[ Writable ]] : 表示属性是否可以被修改。默认是 true
  4. [[ Value ]] : 表示属性的实际值,默认未赋值的情况下是 undefined

例如:

let person = {name: 'mike'
}

这里创建了一个名为 name 的属性,且赋值为 mike ,那么前面三个特性 [[ configurable ]] [[ Enumerable]] [[ Writable ]] 都会是默认值 true , [[ Value ]] 为 ' mike '

2.2 修改默认属性

使用 Object.defineProperty() 方法,接收三个参数:属性对象、属性名称、描述符对象

let person = {name: 'mike'
}
Object.defineProperty(person,"name", {writable: false
})
person.name = 'alice'
console.log(person.name);           // mike

上面的例子,在非严格模式下尝试重新赋值会被忽略,在严格模式下会报错

Tips:

  • 如果把 [[ configurable ]] 设置为 false,该属性变成不可配置后,就不能再变回可配置了。再次调用 Object.defineProperty() 修改除 [[ writable ]] 之外的所有属性都会报错
  • 在调用 Object.defineProperty() 时如果没有给 configurable enumberable writable 指定值,就会默认是 false (例如 3.1 的例子)
  • 多数情况下,可能不需要 Object.defineProperty() 提供这些强大的设置,但要知道这些概念

2.3 访问器属性

访问器属性不包含数值。它们包含一个获取函数(getter)和一个设置函数(setter),不过这两个函数不是必需的。在读取时会调用 getter ,在写入时调用 setter

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

访问器属性有4个特性

  1. [[ configurable ]] : 表示属性是否可以通过 delete 删除并重新定义,是否可以修改他的特性。以及是否可以把它变成访问器属性。默认是 true
  2. [[ Enumerable]] : 表示属性是否可以通过 for-in 循环返回。默认是 true
  3. [[ Get ]] : 获取函数,在读取属性时使用,默认为 undefined
  4. [[ Set ]] : 设置函数,在写入属性时使用,默认为 undefined

例如:

let book = {year_: 2023,    // 数据属性,通常情况下下划线表示该属性并不希望在对象方法的外部使用edition: 1      // 数据属性
};// 定义访问器属性
Object.defineProperty(book,"year", {get() {return this.year_;},set(value) {if(value > 2023) {this.year_ = value;this.edition += value - 2023;}}
});
// 使用访问器属性
book.year = 2025;
console.log(book.edition);    // 3

在上面的例子中,修改 year 属性会导致 year_ 和 edition 都会进行更新。这个就是访问器属性的典型使用场景,设置一个属性会导致其他属性发生一些变化。

Tips:

  • 虽然获取函数和设置函数并不是一定需要定义的。但是如果你只定义了获取函数,也就意味着该属性是只读的,当你想要尝试修改属性时,非严格模式会忽略,严格模式会报错。反之也是如此

3.对象的操作

3.1 定义多个属性 Object.defineProperties( )

Object.defineProperties( ) 接收两个参数,第一个是添加或修改属性的对象,第二个是描述符对象

let book = {};
Object.defineProperties(book,{year_: {                // 数据属性value: 2023}, edition: {             // 数据属性value: 1    },year: {                // 访问器属性get() {return this.year_;},set(value) {if(value > 2023) {this.year_ = value;this.edition += value - 2023;}}}
})

这个例子中定义的 book 对象跟 2.3 例子中的 book 对象是一样的。区别就是数据属性 year_ 和edition 由于没有指定 configurable enumerable 和 writable 特性值,所以全都设置为 false

3.2 读取属性的特性

  • Object.getOwnPropertyDescriptor( )

Object.getOwnPropertyDescriptor( ) 接收两个参数,第一个是要访问的对象名,另一个是属性名(要以字符串的形式)。返回值是一个对象,返回数据属性和访问器属性的四个特性

let book = {};
Object.defineProperties(book,{year_: {                // 数据属性value: 2023}, edition: {             // 数据属性value: 1    },year: {get() {return this.year_;},set(value) {if(value > 2023) {this.year_ = value;this.edition += value - 2023;}}}
})let descriptor = Object.getOwnPropertyDescriptor(book,"year_");
console.log(descriptor);
// {
//   value: 2023,
//   writable: false,
//   enumerable: false,
//   configurable: false
// }let descriptor1 = Object.getOwnPropertyDescriptor(book,"year");
console.log(descriptor1);
// {
//     get: [Function: get],
//     set: [Function: set],
//     enumerable: false,
//     configurable: false
// }
  • Object.getOwnPropertyDescriptors( )

该函数接收一个参数为要访问的对象,返回值是一个对象。该函数实际上会在对象的每个自有属性上调用 Object.getOwnPropertyDescriptor( ) ,合并在一个新对象后返回。

let book = {};
Object.defineProperties(book, {year_: { // 数据属性value: 2023},edition: { // 数据属性value: 1},year: {get() {return this.year_;},set(value) {if (value > 2023) {this.year_ = value;this.edition += value - 2023;}}}
})let descriptors = Object.getOwnPropertyDescriptors(book);
console.log(descriptors);
// {
//     year_: {
//         value: 2023,
//         writable: false,
//         enumerable: false,
//         configurable: false
//     },
//     edition: {
//         value: 1,
//         writable: false,
//         enumerable: false,
//         configurable: false
//     },
//     year: {
//         get: [Function: get],
//         set: [Function: set],
//         enumerable: false,
//         configurable: false
//     }
// }

3.3 合并对象 Object.assign( )

  • Object.assign( ) 这个方法接收一个目标对象和一个或多个源对象作为参数。返回值是修改后的目标对象。
  • 将源对象中可枚举和自有的属性复制到目标对象中。(使用源对象的 [[ Get ]] 特性方法获取值,使用目标对象的 [[ Set ]] 特性方法设置属性值

简单复制

let dest = {a: 'aaa'
}
let src = {b: 'bbb'
}let k = Object.assign(dest,src, { c: 'ccc'} );console.log(dest);
// { a: 'aaa', b: 'bbb', c: 'ccc' }console.log(k);
// { a: 'aaa', b: 'bbb', c: 'ccc' }

获取函数和设置函数

let dest = {set (val) {console.log(`This is ${val}`);}
}let src = {get () {console.log('src getter');return 'foo';}
}Object.assign(dest,src);dest.get();       // src getter

覆盖属性,重复的属性会进行覆盖

let dest = {a: 'aaa',b: 'bbb'
}let src = {a: 'zzz'
}Object.assign(dest, src, { a: 'kkk' });console.log(dest);
// { a: 'kkk', b: 'bbb' }

4.增强的对象语法

4.1 属性值简写

当属性名和变量名相等时,可以直接简写属性名即可。当简写时,如果没有找到同名变量,则会抛出 ReferenceError

let name = 'mike';
function sayName() {console.log(this.name);
}let dest = {name,        // 等价于 name: nameage: 18,sayName     // 函数也适用
}console.log(dest);
// { name: 'mike', age: 18, sayName: [Function: sayName] }dest.sayName();  // mike

4.2 可计算属性

  • 如果想要用一个变量来定义属性名的话,要使用中括号语法,不然会直接识别成字符串。

Tips

  • 变量中途发生改变,要重新定义 person 才会在 person 上生效
let key = 'job';let person = {[key]: 'good'
}console.log(person.job);   // goodkey = 'class';console.log(person.class);    // undefined  要重新定义对象才有用
console.log(person.job);      // good// 重新定义对象 person 变量改动后的值才生效
person = {[key]: 'bad'
}console.log(person.class);   // bad
console.log(person.job);     // undefined
  • 函数返回值也可以充当属性名
let nameKey = 'name';function getKey(count) {return `${nameKey}_${count}`;
}let person = {[getKey(1)] : 'aaa'
}console.log(person);
// { name_1: 'aaa' }

5. 对象解构

ES6 新增了对象结构语法,可以在一条语句中使用嵌套数据实现一个或多个赋值操作。

  • 不解构时
let person = {name: 'mike',age: 18
}
let personName = person.name;
let personAge = person.age;console.log(personName);   // mike
console.log(personAge);    // 18
  • 解构时,简单轻松
let person = {name: 'mike',age: 18
}
let { name: personName, age: personAge } = person;console.log(personName);   // mike
console.log(personAge);    // 18
  • 如果属性名和要赋值的变量名相等,甚至可以简写
let person = {name: 'mike',age: 18
}
let { name, age, job } = person;console.log(name);   // mike
console.log(age);    // 18
console.log(job);    // undefined 当属性不存在时 undefined

Tips:

  • 解构时会自动帮你生成变量,如果要给事先声明过的变量赋值,则表达式必须包含在一对括号中。
let personName,personAge;let person = {name: 'mike',age: 18
};({ name: personName, age: personAge } = person);console.log(personName);    // mike
console.log(personAge);     // 18

终于写完了,不过未完待续......

红宝书系列之 对象(一)相关推荐

  1. 红宝书系列之 对象(二)

    目录 一.创建对象(接口方法) 1.1 工厂模式 1.2 构造函数模式 二.构造函数 2.1 构造函数也是函数 2.2 构造函数的问题 优化 一.创建对象(接口方法) 虽然使用 Object 构造函数 ...

  2. 红宝书系列之 var let const 的区别

    目录 声明风格及最佳实践 var 关键字 1. var 使用 2. var 声明作用域 3. var 声明提升 let 声明 1. let 作用域 2. 暂时性死区 3. 全局声明(网易前端笔试题) ...

  3. 游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总

    游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总 声明:未经作者允许,严禁商用,转载请标明出处和来源,谢谢 转载自:https://www.cnblo ...

  4. 红宝书初步研读随手笔记

    红宝书初步研读系列–第一二三章 红宝书第一遍研读,知识点整理–随手笔记 第一章 什么是JavaScriptS 1.1. JavaScript包括: ECMAScript (核心)DOM(文档对象模型) ...

  5. 《JavaScript高级程序设计(第四版)》红宝书学习笔记(2)(第四章:变量、作用域与内存)

    个人对第四版红宝书的学习笔记.不适合小白阅读.这是part2.持续更新,其他章节笔记看我主页. (记 * 的表示是ES6新增的知识点,记 ` 表示包含新知识点) 第四章:变量.作用域与内存 4.1 原 ...

  6. 《JavaScript高级程序设计(第四版)》红宝书学习笔记(1)

    个人对第四版红宝书的学习笔记.不适合小白阅读.这是part1,包含原书第二章(HTML中的Javascript)和第三章(语言基础).持续更新,其他章节笔记看我主页. (记 * 的表示是ES6新增的知 ...

  7. 《JavaScript高级程序设计》红宝书第二遍阅读(动手实践)

    <JavaScript高级程序设计>红宝书第二遍阅读(动手实践) 第1章--什么是JavaScript 第2章--HTML中的JavaScript 第3章--语言基础 第4章--变量.作用 ...

  8. 《JavaScript高级程序设计》红宝书第一遍阅读(了解概念)

    <JavaScript高级程序设计>红宝书第一遍阅读(了解概念) 第1章--什么是JavaScript 第2章--HTML中的JavaScript 第3章--语言基础 第4章--变量.作用 ...

  9. OpenGL红宝书的部分学习记录

    我看的OpenGL红宝书为: <OpenGL编程指南>-- 原书第9版 OpenGL Programming Guide – The Official Guide to Learning ...

最新文章

  1. ffmpeg 怎么处理udp音频_视音频数据处理入门:UDP-RTP协议解析
  2. The Digits String
  3. koa中间件机制详解
  4. 使用Git版本控制查看文件的更改历史记录
  5. c++ 二维数组_C|数形结合理解数组指针、指针数组、一级指针来遍历二维数组
  6. 网络安全系统性学习路线「全文字详细介绍」
  7. 2020人脸识别报告:上万家企业入局,八大技术六个趋势一文看尽
  8. 浪潮服务器一键还原系统,一键恢复 怎样做备份
  9. ThreadX视频教程第2期:通俗易懂的介绍Cortex-M内核的OS特性,双堆栈,非特权级,PendSV,SVC,Systick等,争取人人都可以掌握
  10. Map集合简单应用的例子(世界杯)
  11. 百度搜索开放平台,百度搜索api
  12. 计算机技术学硕国家线,关于工科国家线专硕学硕
  13. Windows 10 - 安装 Mysql - zip压缩包详细安装教程
  14. 红楼梦评论--王国维
  15. 【信管1.6】计算机网络基础(四)网络规划与数据软件
  16. 计蒜客信息学入门赛 #16--B
  17. 《疯狂Java讲义》(第5版) 作者李刚(待重新排版)
  18. python秒数转化为时间用户jianpang_Python写了个域名注册查询脚本,支持自定义数字,字母,拼音组合以及域名长度....
  19. Windows下安装C环境
  20. 利用ArcGIS结合DEM提取小流域单元

热门文章

  1. 平板电脑是微型计算机吗,精雕细琢 戴尔XT2平板电脑
  2. 一款超简单易用功能丰富的视频播放器Chimee
  3. 用Hive统计某个年阶段连接夺冠的NBA球队
  4. 米线店结账程序 装饰着模式_海底捞推出三个子品牌 主打餐饮10元店模式
  5. 流程图是什么?正确绘制流程图方法介绍
  6. rocket-chat使用教程
  7. python画烟花_python烟花效果的代码实例
  8. vSAN 报警处理:虚拟机的放置和可用性状态不可访问
  9. pytorch_gru理解
  10. android路由框架的好处,严选 Android 路由框架优化(下篇)