JavaScript 中的对象类型

花落花开99 2020-11-07 23:13:35
java c++ javascript prototype hey


什么是对象

简单的说,对象就是一组属性(property)的集合。每个属性包含两部分:

  • 属性名(key)—— 可以是字符串或者符号(symbol)类型值。
  • 特征(attributes)—— 用来描述属性的状态。

属性的分类

对象属性可以分为两类:

  • 数据属性(data property)—— 属性值是可以直接访问的。
  • 访问器属性(accessor property)—— 属性值通过访问器函数(accessor function)来访问的,包含 gettersetter 方法。getter方法用来获取属性值,setter 方法用来设置属性值。换句话说,访问器属性不单独保存属性值,属性值都是通过访问器函数来获取和设置的。

一个属性要么是访问器属性(具有 getter/setter 方法),要么是数据属性(具有 value),但不能两者都是。

示例:

let user = {
// name 和 surname 是数据属性
name: "John",
surname: "Smith",
// fullname 是访问器属性,定义 getter 和 setter 方法不需要使用 function 关键字
get fullName() {
return `${this.name} ${this.surname}`;
},
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
user.name; // John
user.fullName; // John Smith

属性的特征

数据属性中的特征:

Attribute Name Value Domain Description
[[Value]] 属性值。
[[Writable]] Boolean 若是true,则可以修改属性值,否则属性值不可修改。
[[Enumerable]] Boolean 若是true,则可以使用for-in枚举该属性值,否则该属性值不可枚举。
[[Configurable]] Boolean 若是true,则该属性可被删除,可被修改为访问器属性,或者可以修改该属性的部分特征(不能修改[[Value]],不能将[[Writable]]修改为false

访问器属性中的特征:

Attribute Name Value Domain Description
[[Get]] Object or Undefined 若属性值是对象,则必须是函数对象。该函数用来获取属性值。
[[Set]] Object or Undefined 若属性值是对象,则必须是函数对象。该函数用来修改属性值。
[[Enumerable]] Boolean 若是true,则可以使用for-in枚举该属性值,否则该属性值不可枚举。
[[Configurable]] Boolean 若是true,则该属性可被删除,可被修改为数据属性,或者可以修改该属性的特征。

用来描述属性的特征(attribute)是存放在属性描述对象(attributes object)中的,这些特征又被称为属性描述符

通过Object.getOwnPropertyDescriptor()方法可以获取对象属性的属性描述对象

var obj = { p: 'a' };
Object.getOwnPropertyDescriptor(obj, 'p');
// { value: "a",
// writable: true,
// enumerable: true,
// configurable: true
// __proto__: Object
// }

对象的创建

对象的创建有三种方式:

  • 使用初始化器 —— 对象字面量。
  • 使用构造函数 —— 使用new关键字让构造函数返回一个对象实例。
  • 使用Object.create()方法 —— 以现有对象为原型,返回一个新的对象。

初始化器

一个对象初始化器,由大括号 ({}) 和其包含的零个或多个键值对构成。

示例一: ES6 之前的语法

var o = {}; // 这是一个空对象
var o = {a: 'foo', b: 42, c: {}};

**示例二:**ES6 新增的语法

// 属性可以用变量
var a = 'foo', b = 42, c = {};
var o = {a, b, c};
// 若属性值是函数,可省略 function 关键字
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};
// 属性名可以使用变量和表达式
var prop = 'foo';
var o = {
[prop]: 'hey',
['b' + 'ar']: 'there'
};

构造函数

在早期,JavaScript 语言使用构造函数(constructor)作为创建对象的模板。构造函数与普通函数的区别是:函数体内部使用了this关键字表示所要生成的对象实例,生成对象时必须使用new关键字。

function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

这种写法跟传统的面向对象语言(例如 C++ 和 Java)差异很大,让学过 Java 等语言的人感到困惑和费解。后来,ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到。

class Point {
// 构造器
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}

Object.create()方法

以现有的对象作为原型,生成新的实例对象。新生成的对象会继承原型对象的属性。

// 原型对象
var A = {
print: function () {
console.log('hello');
}
};
// 实例对象
var B = Object.create(A);
Object.getPrototypeOf(B) === A // true
B.print() // hello
B.print === A.print // true

Object.create()方法生成的对象,会继承它的原型对象的构造函数。

function A() {}
var a = new A();
var b = Object.create(a);
b.constructor === A // true
b instanceof A // true

属性的操作

属性的查看

使用Object.keys方法查看一个对象本身的所有属性。

var obj = {
key1: 1,
key2: 2
};
Object.keys(obj);
// ['key1', 'key2']

属性的读取

读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。

var obj = {
p: 'Hello World'
};
obj.p // "Hello World"
obj['p'] // "Hello World"

方括号运算符中可以使用变量和表达式。

var foo = 'bar';
var obj = {
foo: 1,
bar: 2
};
obj.foo // 1
obj[foo] // 2

属性的新增和修改

与属性的读取一样,可以使用点运算符或者方括号运算符,来新增或者修改属性。若指定的属性存在,则修改该属性的值;若不存在,则新增该属性。

var obj = {};
// JavaScript 允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。
obj.foo = 'Hello';
obj['bar'] = 'World';

这种方法只能设置属性的值,属性的其他特征都是默认值。

若要对对象属性进行更精细的设置,则可以使用Object.defineProperty()方法来新增或修改属性。它的用法如下:

Object.defineProperty(object, propertyName, attributesObject)

Object.defineProperty方法接受三个参数:

  • object:属性所在的对象
  • propertyName:字符串,表示属性名
  • attributesObject:属性描述对象

若属性不存在,则新增该属性;若属性存在,则更新该属性。该方法的返回值是修改后的对象。

var obj = Object.defineProperty({}, 'p', {
value: 123,
writable: false, // 将属性设置为不可修改
enumerable: true,
configurable: false
});
obj.p // 123
obj.p = 246;
obj.p // 123

属性的删除

delete命令用于删除对象的属性,删除成功后返回true

var obj = { p: 1 };
Object.keys(obj) // ["p"]
delete obj.p // true
obj.p // undefined
Object.keys(obj) // []

相关资料

6.1.7 The Object Type

数据类型-对象

标准库-属性描述对象

JavaScript 标准内置对象-Object

Class 的基本语法

版权声明
本文为[花落花开99]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4686254/blog/4707756

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云