es6 --- 对象的扩展

àì夳堔傛蜴生んèń 2023-07-09 07:24 105阅读 0赞

es6的对象属性

Object.is()

  1. 用来比较两个值是否严格相等,与严格比较运算符( === ) 的行为基本一致
  2. Object.is('foo', 'foo')
  3. // true
  4. Object.is({}, {})
  5. // false

注意:: +0 不等于 -0 NaN等于自身

  1. +0 === -0 //true
  2. NaN === NaN // false
  3. Object.is(+0, -0) // false
  4. Object.is(NaN, NaN) // true

Object.assign(a,b,c)

  1. 用于对象合并,将源对象(source)的所有可枚举属性,复制到目标对象( target )
  2. a 是目标对象 b,c是源对象,也是就需要赋值的对象
  3. 注意: 如果目标对象与源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性
  4. var target = { a: 1, b: 1 };
  5. var source1 = { b: 2, c: 2 };
  6. var source2 = { c: 3 };
  7. Object.assign(target, source1, source2);
  8. target // {a:1, b:2, c:3}

如果只有一个参数,Object.assign()会直接返回这个参数

  1. var obj = {a:1}
  2. Object.assign(obj) === obj

如果该参数不是对象,则会先转化成对象,然后返回

undefined 和 null 无法转化成对象,所以用他们作为参数,就会报错,但是如果这非对象参数的位置在源对象中,就会跳过这些无法转化的对象,因此不会报错.如果在目标对象中,无法跳过,就一定报错

其他类型的值( 即数值 ,字符串 和 布尔值 ) 不在首参数,也不会报错,但是,除了字符串会以数组的形式拷贝到目标对象,其他值都不会产生效果,会被忽略.

  1. var v1 = 'abc';
  2. var v2 = true;
  3. var v3 = 10;
  4. var obj = Object.assign({}, v1, v2, v3);
  5. console.log(obj); // { "0": "a", "1": "b", "2": "c" }

Object.assign()拷贝的属性是有限制的,只拷贝源对象的自身属性( 不拷贝继承属性) ,也不拷贝不可枚举的属性

属性名为Symbol值的属性,会被拷贝

注意: Object.assign() 方法实行的是浅拷贝, 如果遇到同名的属性,会将其覆盖起值

常见的用途:::

  1. 1: 为对象添加属性

x属性和y属性添加到Point类的对象实例

  1. class Point {
  2. constructor(x, y) {
  3. Object.assign(this, {x, y});
  4. }
  5. }

2: 为对象添加方法

  1. Object.assign(SomeClass.prototype, {
  2. someMethod(arg1, arg2) {
  3. ···
  4. },
  5. anotherMethod() {
  6. ···
  7. }
  8. });
  9. // 等同于下面的写法
  10. SomeClass.prototype.someMethod = function (arg1, arg2) {
  11. ···
  12. };
  13. SomeClass.prototype.anotherMethod = function () {
  14. ···
  15. };

3::: 克隆对象

  1. 将原始对象拷贝到一个空对象中,就能得到一个一模一样的原始对象的克隆对象了
  2. function clone(origin) {
  3. return Object.assign({}, origin);
  4. }

不过,采用这种克隆,只能克隆原始对象自身的值,不能克隆它继承的值.如果想要保持继承链,可以采用以下方式:

  1. function clone(origin) {
  2. let originProto = Object.getPrototypeOf(origin);
  3. return Object.assign(Object.create(originProto), origin);
  4. }

4::: 合并多个对象

将多个对象合并到某个对象中去,第一个参数为目标对象,后面是源对象

  1. const merge =
  2. (target, ...sources) => Object.assign(target, ...sources);

如果希望合并后返回一个新对象,可以改写上面函数,对一个空对象合并。

  1. const merge =
  2. (...sources) => Object.assign({}, ...sources);

5::: 为属性指定默认值

  1. const DEFAULTS = {
  2. logLevel: 0,
  3. outputFormat: 'html'
  4. };
  5. function processContent(options) {
  6. options = Object.assign({}, DEFAULTS, options);
  7. }

注意:: 存在深拷贝的问题

属性的可枚举性

对象的每个属性都有一个描述对象,用来控制该属性的行为.

Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

描述对象的enumerable属性,称为’可枚举性’,如果该属性为false,就表示某些操作会忽略当前属性.

以下这几个操作都会忽略enumerable属性

for …in :: 只会遍历对象自身的和继承的可枚举的属性

  1. Object.keys() :: 返回对象自身的所有可枚举的属性的键名

JSON.stringify() :: 只串行对象自身的可枚举的属性

Object.assign) :: 只拷贝对象自身的可枚举的属性

另外,es6规定,所有的class的原型的方法都是不可枚举的

属性的遍历

1:: for … in 循环遍历对象自身的和继承的可枚举属性( 不包含symbol属性 )

2:: Object.keys() 返回一个数组,包括对象自身的( 不含继承的 ) 所有可枚举的属性( 不含symbol )

3:: Object.getOwnPropertyNames(obj) 返回一个数组,包括对象自身的所有属性( 不含symbol属性,但是包括不可枚举属性)

4:: Object.getOwnPropertySymbols(obj) 返回一个数组.包含对象自身的所有symbol属性

5:: Reflect.ownKeys(obj) 返回一个数组,包含对象自身的所有属性,不管是属性名是symbol或者字符串.也不管是否可枚举

以上的5种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。

  • 首先遍历所有属性名为数值的属性,按照数字排序。
  • 其次遍历所有属性名为字符串的属性,按照生成时间排序。
  • 最后遍历所有属性名为Symbol值的属性,按照生成时间排序。

_proto_

如果一个对象本身部署了_proto_属性,则该属性的值就是对象的原型

_proto_属性(前后各两个下划线) ,用来读取或设置当前对象的prototype对象.

它的本质是一个内部属性,并不是api,只是浏览器广泛支持.而且只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好不要使用这个属性,可以使用Object.setPrototypeOf() 写操作 , Object.getPrototypeOf() 读操作 , Object.create() 生成操作

在实现上,__proto__调用的是Object.prototype.__proto__,具体实现如下。

  1. Object.defineProperty(Object.prototype, '__proto__', {
  2. get() {
  3. let _thisObj = Object(this);
  4. return Object.getPrototypeOf(_thisObj);
  5. },
  6. set(proto) {
  7. if (this === undefined || this === null) {
  8. throw new TypeError();
  9. }
  10. if (!isObject(this)) {
  11. return undefined;
  12. }
  13. if (!isObject(proto)) {
  14. return undefined;
  15. }
  16. let status = Reflect.setPrototypeOf(this, proto);
  17. if (!status) {
  18. throw new TypeError();
  19. }
  20. },
  21. });
  22. function isObject(value) {
  23. return Object(value) === value;
  24. }

Object.setPrototypeOf()

用来设置一个对象的prototype对象

  1. // 格式
  2. Object.setPrototypeOf(object, prototype)
  3. // 用法
  4. var o = Object.setPrototypeOf({}, null);
  5. function (obj, proto) {
  6. obj.__proto__ = proto;
  7. return obj;
  8. }

Object.getPrototypeOf()

用来读取一个对象的prototype对象

  1. Object.getPrototypeOf(obj);
  2. function Rectangle() {
  3. }
  4. var rec = new Rectangle();
  5. Object.getPrototypeOf(rec) === Rectangle.prototype
  6. // true
  7. Object.setPrototypeOf(rec, Object.prototype);
  8. Object.getPrototypeOf(rec) === Rectangle.prototype
  9. // false

Object.keys()

遍历属性的键名,返回一个数组,成员是参数对象自身的(不含继承)所有可以遍历的(enumerable)

  1. var obj = { foo: "bar", baz: 42 };
  2. Object.keys(obj)
  3. // ["foo", "baz"]

Object.values()

遍历属性的键值,返回一个数组,成员参数是对象自身的(不含继承)所有可遍历(enumerable)属性的键值

  1. var obj = { foo: "bar", baz: 42 };
  2. Object.values(obj)
  3. // ["bar", 42]

object.values()会过滤属性名为Symbol值的属性,如果参数是一个字符串,会返回各个字符组成的一个数组

字符串会先转化成一个类似数组的对象.字符串的每个字符,就是该对象的一个属性.因此Object.values()

返回每个属性的键值,就是各个字符组成的一个数组

如果参数不是对象,会先将其转化成对象,由于数值和布尔值的包装对象,都不会为实例添加非继承的属性,会返回空数组

  1. Object.values(42) // []
  2. Object.values(true) // []

Object.entries()

遍历属性的键值对数组,返回一个数组,成员是参数对象自身的(不可继承)所有可遍历的属性的键值对数组

忽略Symbol值的属性

Object.entries方法的一个用处是,将对象转为真正的Map结构

  1. var obj = { foo: 'bar', baz: 42 };
  2. var map = new Map(Object.entries(obj));
  3. map // Map { foo: "bar", baz: 42 }

对象的扩展运算符(…)

( 具体内容移步到es6——-数组的扩展中,链接:: https://mp.csdn.net/console/editor/html/104451458)

Object.getOwnPropertyDescriptors()

返回某个对象属性的描述对象

附加:

对象的创建方法:

  1. //第一种
  2. var person = new Object()
  3. person.name = 'clover'
  4. person.age = 18
  5. person.sex = '女'
  6. person.job = '前端开发'
  7. document.write(person.name + '是一个' + person.job)
  8. //第二种
  9. var person = {name: 'clover',age:18,sex:'女',job:'前端开发'}
  10. //第三种
  11. function person(name,age,sex,job){
  12. this.name = name
  13. this.age = age
  14. this.sex = sex
  15. this.job = job
  16. }
  17. var info = new person('clover',18,'女','前端开发')

对象循环

  1. var text = ''
  2. var person = {name:'clover',age:18,job:'it'}
  3. for(i in person){
  4. text += person[i]
  5. }

发表评论

表情:
评论列表 (有 0 条评论,105人围观)

还没有评论,来说两句吧...

相关阅读

    相关 es6 对象扩展

    1.属性的简洁表示法     function f(x,y) \{       return \{x,y\};     \}     // 等同于     funct

    相关 ES6-对象扩展

    在[JavaScript原生对象-Object对象详解][JavaScript_-Object]中已经比较详细的介绍了Object对象,其中已经多次提高了ES6,这一篇将详细的

    相关 ES6 对象扩展

    属性的简洁表示法 ES6允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。 下面代码表明,ES6允许在对象之中,直接写变量。这时,属性名为变量名, 属