对象

  • 对象
  • 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 对象的新增方法

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方法返回一个数组,包含了参数对象的所有属性。这个数组的属性次序是这样的,首先是数值属性210,其次是字符串属性ba,最后是 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,表示某些操作会忽略当前属性。

下面四个操作会忽略enumerablefalse的属性。

  • for...in循环:只遍历对象自身的和继承的可枚举的属性。返回继承的属性
  • Object.keys():返回对象自身的所有可枚举的属性的键名。忽略继承的属性,只处理对象自身的属性
  • JSON.stringify():只串行化对象自身的可枚举的属性。忽略继承的属性,只处理对象自身的属性
  • Object.assign(): 忽略enumerablefalse的属性,只拷贝对象自身的可枚举的属性。忽略继承的属性,只处理对象自身的属性,ES6 新增的

实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉for...in操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的toString方法,以及数组的length属性,就通过“可枚举性”,从而避免被for...in遍历到。

2 赋值

2.1 赋值方法

  1. 定义时初始化
let obj = {foo: 123}; // obj = {foo: 123}
  1. 动态创建,不必在对象声明时就指定
let obj = {};
obj.foo = 123; // obj = {foo: 123}
  1. 属性的简洁表示
  • ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
  • 属性名就是变量名, 属性值就是变量值
const foo = 'bar';
const obj = {foo}; // obj = {foo: "bar"}
  1. 扩展运算符 解构赋值
  • 将目标对象自身的所有可遍历的(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`),将它们连同值一起拷贝过来
  1. 扩展运算符 取出对象可遍历属性
  • 对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
  • 扩展运算符后面必须是一个变量名
  • 给对象加元素: 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相关推荐

  1. JavaScript对象(Object)

    JavaScript对象 对象(Object) 对象的创建 使用{}创建 使用Object创建 使用Function创建 使用class关键字 对象的原型模型 对象(Object) 对象由花括号分隔, ...

  2. JavaScript 对象总结

    JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象 JavaScript 对象 对象只是一种特殊的数据.对象拥有属性和方法 访问对象 ...

  3. 《JavaScript启示录》——1.21 JavaScript对象和Object()对象

    本节书摘来自异步社区<JavaScript启示录>一书中的第1章,第1.21节,作者:[美]Cody Lindley著,更多章节内容可以访问云栖社区"异步社区"公众号查 ...

  4. javascript对象包含哪些要素_让人迷糊的JavaScript对象(Object一)

    对于很多初学的小伙伴听到JavaScript内置对象.BOM.DOM.WEB API等关键词基本上都是迷糊,不是很明白他们之间的关系,以及他们是如果建立联系的.虽然我们现在小伙伴在学VUE,React ...

  5. JavaScript 函数定义+内置函数使用+array对象+object类型

    文章目录 函数定义 random() setInterval() setTimeout() 数组对象 object 函数定义 两种格式: function 自定义函数名称(参数1,参数2,...,参数 ...

  6. JavaScript对象类型Object

    前言 系统学习JavaScript,由于有3年的java后端开发经验,并且有2年的JavaScript+Jquery开发经验,所以像编程语言的一些通用知识就直接跳过了,重点关注JavaScript的语 ...

  7. JavaScript系列之内置对象Object

    文章の目录 一.静态方法 1.Object.assign() 1.1.概述 1.2.语法 1.3.参数 1.4.返回值 1.5.描述 1.6.示例 2.Object.create() 2.1.概述 2 ...

  8. JavaScript中Object对象方法超详细讲解举例说明仅此一篇

    JavaScript中Object对象方法超详细讲解举例说明仅此一篇 Object.assign() Object.create() Object.values() Object.entries() ...

  9. javascript 回顾一下 基础标准内置对象 Object(二)

    文章目录 一.Object 二.Object 构造函数的属性 1.Object.length 2.Object.prototype 3.Object.assign() 4.Object.create( ...

最新文章

  1. arduino跑python,尝试在我的Arduino和stu上执行Python3.7.2中的代码
  2. .net里鼠标选中的text数据怎么获取_Python数据科学实践 | 爬虫1
  3. 手把手教你用Prophet快速进行时间序列预测(附Prophet和R代码)
  4. 线程与消息循环的关系
  5. java后端传object给js_【JSON】JSON在前端和后端传递
  6. java解析json文件_Java性能优化:正确的解析JSON文件
  7. 13 年 29 款手机,从激进到求稳,iPhone 都经历什么?
  8. 广联达提示盗版文件修复工具
  9. OpenCV中集成目标跟踪算法介绍
  10. 怎么用c语言表示素数,用C语言编写判断一个数是否是素数的程序
  11. Excel2007打开文件时,不显示内容,需要拖拽进去才能显示
  12. PCIE学习笔记(五)PIO例程设计与仿真分析
  13. r星服务器无响应,gta5r星游戏服务器出现了未知错误 | 手游网游页游攻略大全
  14. linux图片裁剪软件安卓版,照片裁剪软件下载-照片裁剪 安卓版v2.2-PC6安卓网
  15. 图解CRM(客户关系管理)全流程
  16. java通过jstack命令查询日志深入理解
  17. *7-1 CCF 2015-09-1 数列分段
  18. 攻击JavaWeb应用————2、CS交互安全
  19. JAVA动态代理实现
  20. 原力计划第6周榜单揭晓!

热门文章

  1. QQ群78928780记录整理:90521-精华
  2. 暑期练习web25:web code(i春秋)index.php文件包含、base64图片加密
  3. [打破常识]“木桶原理”之大谬误!
  4. DNSPod x QQ音乐,守护周杰伦“奇迹现场重映计划”千万级线上直播
  5. 湾区4.4级地震,这些APP用得着!
  6. 免费PDF拆分合并工具
  7. 计算机网络安装维护经验,宽带维护经验和安装技巧
  8. 四级单词pdf_2018年12月大学英语四级真题及答案解析(完整三套可打印)
  9. BLE ATT和GATT小结
  10. 家居O2O平台有哪些?