【JavaScript】 对象 Object
对象
- 对象
- 1 属性 property
- 1.1 属性创建
- 1.2 属性取值
- 1.3 属性删除 delete
- 1.4 属性存在 in
- 1.5 属性遍历 keys
- 1.7 属性描述对象
- 1.7.1 属性可枚举性
- 2 赋值
- 2.1 赋值方法
- 2.1.1 解构赋值
- 2.1.2 扩展运算符
- 2.2 数据同步更改
- 3 Object 对象
- 3.1 Object 属性
- 3.2 Object()
- 3.3 Object 静态方法
- 3.4 Object 实例方法
对象
- js 对象
- js Object对象
- es6 对象的拓展
- es6 对象的新增方法
- 对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合
- 对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以
- 如果键名是数值,会被自动转为字符串。
- 对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型
1 属性 property
1.1 属性创建
- 属性可以动态创建,不必在对象声明时就指定。
var obj = {};
obj.foo = 123;
obj.foo; // 123
- 属性的简洁表示
- ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
- 属性名就是变量名, 属性值就是变量值
const foo = 'bar';// 简写
const baz = {foo}; // baz = {foo: "bar"}// 等同于
const baz = {foo: foo};
1.2 属性取值
- 读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。
var obj = { p: "Hello World" };obj.p; // "Hello World"
obj["p"]; // "Hello World"
with
语句的格式如下:
with (对象) {语句;
}
- 它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
// 例一
var obj = {p1: 1,p2: 2,
};
with (obj) {p1 = 4;p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;// 例二
with (document.links[0]) {console.log(href);console.log(title);console.log(style);
}
// 等同于
console.log(document.links[0].href);
console.log(document.links[0].title);
console.log(document.links[0].style);
1.3 属性删除 delete
delete
命令用于删除对象的属性,删除成功后返回true
。
var obj = { p: 1 };
Object.keys(obj); // ["p"]delete obj.p; // true
obj.p; // undefined
Object.keys(obj); // []
1.4 属性存在 in
in
运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),- 如果包含就返回
true
,否则返回false
。它的左边是一个字符串,表示属性名,右边是一个对象。
var obj = { p: 1 };
"p" in obj; // true
"toString" in obj; // true
1.5 属性遍历 keys
Object.keys
:查看一个对象本身的所有属性
var obj = { key1: 1, key2: 2};Object.keys(obj); // ['key1', 'key2']
Object.getOwnPropertyNames
:查看一个对象本身的所有属性- 数组的
length
属性是不可枚举的属性,所以只出现在Object.getOwnPropertyNames
方法的返回结果中。
- 数组的
for...in
循环用来遍历一个对象的全部属性。for...in
循环遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。- 它不仅遍历对象自身的属性,还遍历继承的属性。
- 举例来说,对象都继承了
toString
属性,但是for...in
循环不会遍历到这个属性。
var obj = { a: 1, b: 2, c: 3 };for (var i in obj) {console.log("键名:", i); // 键名: a // 键名: b // 键名: cconsole.log("键值:", obj[i]); // 键值: 1 // 键值: 2 // 键值: 3
}
ES6 一共有 5 种方法可以遍历对象的属性。
for...in
循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。Object.keys
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。Object.getOwnPropertyNames
返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。Object.getOwnPropertySymbols
返回一个数组,包含对象自身的所有 Symbol 属性的键名。Reflect.ownKeys
返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
- 首先遍历所有数值键,按照数值升序排列。
- 其次遍历所有字符串键,按照加入时间升序排列。
- 最后遍历所有 Symbol 键,按照加入时间升序排列。
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]
上面代码中,Reflect.ownKeys
方法返回一个数组,包含了参数对象的所有属性。这个数组的属性次序是这样的,首先是数值属性2
和10
,其次是字符串属性b
和a
,最后是 Symbol 属性。
1.7 属性描述对象
- JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributes object)
- 属性描述对象提供 6 个元属性。
{value: 123, writable: false,enumerable: true,configurable: false,get: undefined,set: undefined
}
- 对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
// {// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
value
是该属性的属性值,默认为undefined
。writable
是一个布尔值,表示属性值(value)是否可改变(即是否可写),默认为true
。enumerable
是一个布尔值,表示该属性是否可遍历,默认为true
。如果设为false
,会使得某些操作(比如for...in
循环、Object.keys()
)跳过该属性。configurable
是一个布尔值,表示属性的可配置性,默认为true
。如果设为false
,将阻止某些操作改写属性描述对象,比如无法删除该属性,也不得改变各种元属性(value
属性除外)。也就是说,configurable
属性控制了属性描述对象的可写性。get
是一个函数,表示该属性的取值函数(getter),默认为undefined
。set
是一个函数,表示该属性的存值函数(setter),默认为undefined
。Object.getOwnPropertyDescriptor()
方法可以获取属性描述对象。它的第一个参数是目标对象,第二个参数是一个字符串,对应目标对象的某个属性名。Object.getOwnPropertyNames
方法返回一个数组,成员是参数对象自身的全部属性的属性名,不管该属性是否可遍历。
1.7.1 属性可枚举性
对象的每个属性都有一个描述对象(Descriptor),描述对象的“可枚举性”enumerable
属性为false
,表示某些操作会忽略当前属性。
下面四个操作会忽略enumerable
为false
的属性。
for...in
循环:只遍历对象自身的和继承的可枚举的属性。返回继承的属性Object.keys()
:返回对象自身的所有可枚举的属性的键名。忽略继承的属性,只处理对象自身的属性JSON.stringify()
:只串行化对象自身的可枚举的属性。忽略继承的属性,只处理对象自身的属性Object.assign()
: 忽略enumerable
为false
的属性,只拷贝对象自身的可枚举的属性。忽略继承的属性,只处理对象自身的属性,ES6 新增的
实际上,引入“可枚举”(enumerable
)这个概念的最初目的,就是让某些属性可以规避掉for...in
操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的toString
方法,以及数组的length
属性,就通过“可枚举性”,从而避免被for...in
遍历到。
2 赋值
2.1 赋值方法
- 定义时初始化
let obj = {foo: 123}; // obj = {foo: 123}
- 动态创建,不必在对象声明时就指定
let obj = {};
obj.foo = 123; // obj = {foo: 123}
- 属性的简洁表示
- ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
- 属性名就是变量名, 属性值就是变量值
const foo = 'bar';
const obj = {foo}; // obj = {foo: "bar"}
- 扩展运算符 解构赋值
将目标对象自身的所有可遍历的(enumerable)、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。
解构赋值要求等号右边是一个对象
解构赋值必须是最后一个参数
变量必须与属性同名,才能取到正确的值,顺序不对没事
真正被赋值的是属性后面的变量,而不是属性。
默认:
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
改名:const { x, y: z } = { x: 1, y: 2 }
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 } 获取等号右边的所有尚未读取的键(`a`和`b`),将它们连同值一起拷贝过来
- 扩展运算符 取出对象可遍历属性
- 对象的扩展运算符(
...
)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。 - 扩展运算符后面必须是一个变量名
- 给对象加元素:
v = {...v, xxx: y}
let x = 5;
let z = { a: 3, b: 4 };
let n = { x, ...z };
n // {c: 5, a: 3, b: 4}
2.1.1 解构赋值
注意,解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。
let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b // 2
// `x`是解构赋值所在的对象,拷贝了对象`obj`的`a`属性。`a`属性引用了一个对象,修改这个对象的值,会影响到解构赋值对它的引用。
- 扩展运算符的解构赋值,不能复制继承自原型对象的属性。
let o1 = { a: 1 };
let o2 = { b: 2 };
o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined
// 上面代码中,对象`o3`复制了`o2`,但是只复制了`o2`自身的属性,没有复制它的原型对象`o1`的属性。
2.1.2 扩展运算符
- 由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组。
- 如果扩展运算符后面是一个空对象,则没有任何效果。
- 如果扩展运算符后面不是对象,则会自动将其转为对象。
- 如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象。
- 对象的扩展运算符,只会返回参数对象自身的、可枚举的属性,这一点要特别小心,尤其是用于类的实例对象时。
{ ...['a', 'b', 'c'] } // {0: "a", 1: "b", 2: "c"}
{...'hello'} // {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
{...{}, a: 1} // { a: 1 }
{...1} // {} // 等同于 {...Object(1)} 等同于 {...Number{1}}
{...true} // {} // 等同于 {...Object(true)}
{...undefined} // {} // 等同于 {...Object(undefined)}
{...null} // {} // 等同于 {...Object(null)}
- 对象的扩展运算符等同于使用
Object.assign()
方法。
let ab = { ...a, ...b };
// 等同于
let ab = Object.assign({}, a, b);
- 如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。
let aWithOverrides = { ...a, x: 1, y: 2 };
// 等同于
let aWithOverrides = { ...a, ...{ x: 1, y: 2 } };
// 等同于
let x = 1, y = 2, aWithOverrides = { ...a, x, y };
// 等同于
let aWithOverrides = Object.assign({}, a, { x: 1, y: 2 });
上面代码中,a
对象的x
属性和y
属性,拷贝到新对象后会被覆盖掉。
这用来修改现有对象部分的属性就很方便了。
let newVersion = {...previousVersion,name: 'New Name' // Override the name property
};
上面代码中,newVersion
对象自定义了name
属性,其他属性全部复制自previousVersion
对象。
如果把自定义属性放在扩展运算符前面,就变成了设置新对象的默认属性值。
let aWithDefaults = { x: 1, y: 2, ...a };
// 等同于
let aWithDefaults = Object.assign({}, { x: 1, y: 2 }, a);
// 等同于
let aWithDefaults = Object.assign({ x: 1, y: 2 }, a);
2.2 数据同步更改
- 如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。
var o1 = {};
var o2 = o1;o1.a = 1;
o2.a; // 1o2.b = 2;
o1.b; // 2
- 问题:变量赋值,修改变量会导致原始数据也同步发生改变
- 原因:指向同一个地址
- 解决:
JSON.parse(JSON.stringify(config.data))
转换为字符串再转换为对象后赋值
Vue中变量赋值后,修改变量,赋值数据与被赋值数据同步改变
类似的,在 vue 中,变量赋值,修改变量会导致原始数据也同步发生改变
- 问题:let a = this.file, 修改 a 时,this.file 也改变了
- 原因:这是一个引用传递而不是值传递
- 解决:把 this.file 转换为字符串再转换为对象后赋值
let a = JSON.parse(JSON.stringify(this.file));
3 Object 对象
- JavaScript 的所有其他对象都继承自
Object
对象,即那些对象都是Object
的实例。 Object
对象的原生方法分成两类Object
静态方法:直接定义在Object
对象的方法Object
实例方法:定义在Object
原型对象Object.prototype
上的方法。它可以被Object
实例直接使用
// 静态方法
Object.print = function (o) {console.log(o);
};
// 实例方法
Object.prototype.print = function () {console.log(this);
};var obj = new Object(); //实例`obj`直接继承了`Object.prototype`的属性和方法
obj.print(); // Object
3.1 Object 属性
- constructor 指向 Object 构造函数,构造用
- proto 指向原型对象,原型链,
__proto__
属性(前后各两个下划线),用来读取或设置当前对象的原型对象(prototype)。目前,所有浏览器(包括 IE11)都部署了这个属性。
3.2 Object()
Object()
将任意值转为对象:Object
本身是一个函数,可以当作工具方法使用,将任意值转为对象。Object()
构造函数:Object
不仅可以当作工具函数使用,还可以当作构造函数使用,即前面可以使用new
命令。
3.3 Object 静态方法
(1)对象属性模型的相关方法
Object.keys
:查看一个对象本身的所有属性,返回一个包含所有给定对象自身可枚举属性名称是数组Object.getOwnPropertyNames
:查看一个对象本身的所有属性,返回一个数组,成员是参数对象自身的全部属性的属性名,不管该属性是否可遍历。- 数组的
length
属性是不可枚举的属性,所以只出现在Object.getOwnPropertyNames
方法的返回结果中。
- 数组的
Object.getOwnPropertyDescriptor()
:获取某个属性的描述对象。它的第一个参数是目标对象,第二个参数是一个字符串,对应目标对象的某个属性名。Object.getOwnPropertyDescriptors()
方法,返回指定对象所有自身属性(非继承属性)的描述对象。ES2017 引入Object.defineProperty()
:通过描述对象,定义某个属性。给对象添加一个属性并指定该属性的配置Object.defineProperties()
:通过描述对象,定义多个属性。Object.hasOwn()
:也可以判断是否为自身的属性。
(2)控制对象状态的方法
Object.preventExtensions()
:防止对象扩展。Object.isExtensible()
:判断对象是否可扩展。Object.seal()
:禁止对象配置。Object.isSealed()
:判断一个对象是否可配置。Object.freeze()
:冻结一个对象。Object.isFrozen()
:判断一个对象是否被冻结。
(3)原型链相关方法
Object.is()
比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致Object.assign()
通过复制一个或者多个对象,创建一个对象,浅拷贝,方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。Object.values()
返回给定对象自身可枚举属性的键值的数组Object.create()
:该方法可以指定原型对象和属性,返回一个新的对象。Object.entries()
:方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。Object.fromEntries()
方法是Object.entries()
的逆操作,用于将一个键值对数组转为对象。Object.getPrototypeOf()
:获取对象的Prototype
对象。该方法与Object.setPrototypeOf
方法配套,用于读取一个对象的原型对象。Object.setPrototypeOf
:方法的作用与__proto__
相同,用来设置一个对象的原型对象(prototype),返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
Object.assign(obj1, obj2, obj3)
- 合并对象: 把 obj2、obj3 合并到 obj1 上
- 如果不是对象的话,它会在内部转换成对象
- 所以如果碰到了 null 或者 undefined 这种不能转换成对象的值的话,assign 就会报错。
- 但是如果源对象 (如 obj2、obj3) 的参数位置,接收到了无法转换为对象的参数的话,会忽略这个源对象参数。
- 如果在这个过程中出现同名的属性(方法),后合并的属性(方法)会覆盖之前的同名属性(方法)
3.4 Object 实例方法
Object.prototype.valueOf()
:返回当前对象对应的值。Object.prototype.toString()
:返回当前对象对应的字符串形式。Object.prototype.toLocaleString()
:返回当前对象对应的本地字符串形式。Object.prototype.hasOwnProperty()
:判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。Object.prototype.isPrototypeOf()
:判断当前对象是否为另一个对象的原型。返回一个布尔值,看当前对象是否在指定对象的原型链上Object.prototype.propertyIsEnumerable()
:判断某个属性是否可枚举。Object.prototype.hasPrototypeProperty()
:从字面上就可以知道是检测原型对象上的属性。对象位于原型中,则返回true。
Object.prototype.toString()
- 数组、字符串、函数、Date 对象都分别部署了自定义的
toString
方法,覆盖了Object.prototype.toString
方法。
[1, 2, 3].toString(); // "1,2,3"
var obj = {};
obj.toString(); // "[object Object]"
- 上面代码调用空对象的
toString
方法,结果返回一个字符串object Object
,其中第二个Object
表示该值的构造函数。 - 由于实例对象可能会自定义
toString
方法,覆盖掉Object.prototype.toString
方法,所以为了得到类型字符串,最好直接使用Object.prototype.toString
方法。通过函数的call
方法,可以在任意值上调用这个方法,帮助我们判断这个值的类型。
Object.prototype.toString.call(value);
不同数据类型的
Object.prototype.toString
方法返回值如下。- 数值:返回
[object Number]
。 - 字符串:返回
[object String]
。 - 布尔值:返回
[object Boolean]
。 - undefined:返回
[object Undefined]
。 - null:返回
[object Null]
。 - 数组:返回
[object Array]
。 - arguments 对象:返回
[object Arguments]
。 - 函数:返回
[object Function]
。 - Error 对象:返回
[object Error]
。 - Date 对象:返回
[object Date]
。 - RegExp 对象:返回
[object RegExp]
。 - 其他对象:返回
[object Object]
。
- 数值:返回
这就是说,
Object.prototype.toString
可以看出一个值到底是什么类型。
Object.prototype.toString.call(2); // "[object Number]"
Object.prototype.toString.call(""); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(Math); // "[object Math]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
【JavaScript】 对象 Object相关推荐
- JavaScript对象(Object)
JavaScript对象 对象(Object) 对象的创建 使用{}创建 使用Object创建 使用Function创建 使用class关键字 对象的原型模型 对象(Object) 对象由花括号分隔, ...
- JavaScript 对象总结
JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象 JavaScript 对象 对象只是一种特殊的数据.对象拥有属性和方法 访问对象 ...
- 《JavaScript启示录》——1.21 JavaScript对象和Object()对象
本节书摘来自异步社区<JavaScript启示录>一书中的第1章,第1.21节,作者:[美]Cody Lindley著,更多章节内容可以访问云栖社区"异步社区"公众号查 ...
- javascript对象包含哪些要素_让人迷糊的JavaScript对象(Object一)
对于很多初学的小伙伴听到JavaScript内置对象.BOM.DOM.WEB API等关键词基本上都是迷糊,不是很明白他们之间的关系,以及他们是如果建立联系的.虽然我们现在小伙伴在学VUE,React ...
- JavaScript 函数定义+内置函数使用+array对象+object类型
文章目录 函数定义 random() setInterval() setTimeout() 数组对象 object 函数定义 两种格式: function 自定义函数名称(参数1,参数2,...,参数 ...
- JavaScript对象类型Object
前言 系统学习JavaScript,由于有3年的java后端开发经验,并且有2年的JavaScript+Jquery开发经验,所以像编程语言的一些通用知识就直接跳过了,重点关注JavaScript的语 ...
- JavaScript系列之内置对象Object
文章の目录 一.静态方法 1.Object.assign() 1.1.概述 1.2.语法 1.3.参数 1.4.返回值 1.5.描述 1.6.示例 2.Object.create() 2.1.概述 2 ...
- JavaScript中Object对象方法超详细讲解举例说明仅此一篇
JavaScript中Object对象方法超详细讲解举例说明仅此一篇 Object.assign() Object.create() Object.values() Object.entries() ...
- javascript 回顾一下 基础标准内置对象 Object(二)
文章目录 一.Object 二.Object 构造函数的属性 1.Object.length 2.Object.prototype 3.Object.assign() 4.Object.create( ...
最新文章
- arduino跑python,尝试在我的Arduino和stu上执行Python3.7.2中的代码
- .net里鼠标选中的text数据怎么获取_Python数据科学实践 | 爬虫1
- 手把手教你用Prophet快速进行时间序列预测(附Prophet和R代码)
- 线程与消息循环的关系
- java后端传object给js_【JSON】JSON在前端和后端传递
- java解析json文件_Java性能优化:正确的解析JSON文件
- 13 年 29 款手机,从激进到求稳,iPhone 都经历什么?
- 广联达提示盗版文件修复工具
- OpenCV中集成目标跟踪算法介绍
- 怎么用c语言表示素数,用C语言编写判断一个数是否是素数的程序
- Excel2007打开文件时,不显示内容,需要拖拽进去才能显示
- PCIE学习笔记(五)PIO例程设计与仿真分析
- r星服务器无响应,gta5r星游戏服务器出现了未知错误 | 手游网游页游攻略大全
- linux图片裁剪软件安卓版,照片裁剪软件下载-照片裁剪 安卓版v2.2-PC6安卓网
- 图解CRM(客户关系管理)全流程
- java通过jstack命令查询日志深入理解
- *7-1 CCF 2015-09-1 数列分段
- 攻击JavaWeb应用————2、CS交互安全
- JAVA动态代理实现
- 原力计划第6周榜单揭晓!
热门文章
- QQ群78928780记录整理:90521-精华
- 暑期练习web25:web code(i春秋)index.php文件包含、base64图片加密
- [打破常识]“木桶原理”之大谬误!
- DNSPod x QQ音乐,守护周杰伦“奇迹现场重映计划”千万级线上直播
- 湾区4.4级地震,这些APP用得着!
- 免费PDF拆分合并工具
- 计算机网络安装维护经验,宽带维护经验和安装技巧
- 四级单词pdf_2018年12月大学英语四级真题及答案解析(完整三套可打印)
- BLE ATT和GATT小结
- 家居O2O平台有哪些?