当前位置:   article > 正文

【JavaScript进阶之旅 ES6篇 第九章】对象密封的四种方式、is()、assign()、取值函数的拷贝_js isassign

js isassign

一、获取getter、setter的函数名

1、正常方法获取

const obj = {
get foo() {},

set foo(x) {}
}

console.log(obj.foo.name); // 会报错

2、通过Object.getOwnPropertyDescriptor获取

● 通过get|set来获取属性名

const obj = {
get foo() {},

set foo(x) {}
}

var descriptor = Object.getOwnPropertyDescriptor(obj, ‘foo’);

console.log(descriptor.get.name); // get foo
console.log(descriptor.set.name); // set foo

二、对象密封的四种方式

1、对象常量

● 对象常量:不可修改、不可删除(可以添加属性)
a. configurable: false
b. writable: false

const obj = {};

Object.defineProperty(obj, ‘a’,{
configurable: false,
writable: false,
});

obj.b = 1;

console.log(obj); // {b: 1}

2、Object.preventExtensions()

● 禁用添加属性功能

const obj = {
a: 1
}

// 将对象密封,禁用对象添加属性功能
var test = Object.preventExtensions(obj);
console.log(test === obj); // true

// 通过点语法添加属性,他的属性描述符都为true
obj.b = 3;

// 通过defineProperty添加属性,他的属性描述符都为false
Object.defineProperty(obj, ‘c’, {
value: 4
});

console.log(obj); // {a: 1}

严格模式中报错

‘use strict’;

const obj = {};
Object.preventExtensions(obj);
obj.b = 1;

console.log(obj); // 报错

Object.isExtensible()

● 判断对象是否可拓展
● 返回值:true|false
○ false:不可拓展
○ true:可拓展

console.log(Object.isExtensible()); // false

3、Object.seal()

● 密封对象
● 返回值:原对象的引用
● 本质是在调用preventExtensions,然后把循环到的属性的描述符configurable设置为false

Object.isSealed()

● 判断该对象是否是密封对象
● 返回值:true密封的|false不密封的

const obj = {};

Object.seal(obj);

obj.a = 1;
console.log(obj); // {}

console.log(Object.isSealed(obj)); // true

4、Object.freeze()

● 冻结对象
● 返回值:原对象的引用

Object.isFrozen()

● 判断该对象是否冻结
● 返回值:true是冻结对象|false不是冻结对象

三、Object.is()

● 比较运算符的扩充:判断是否相等

console.log(NaN === NaN); // false
console.log(+0 === -0); // true

console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(+0, -0); // false

console.log({} === {}); // false
console.log(Object.is({}, {})); // false

四、Object.assign()

● 对象的合并
● 参数:
a. tar:目标对象
b. source:需要合并的对象
● 返回值:返回目标对象的引用

const obj = {a : 1};
const tar = {};

const res = Object.assign(tar, obj);
console.log(res, tar, res === tar); // { a: 1 } { a: 1 } true

1、合并多个对象

const obj = {a: 1},
obj2 = {b: 2},
obj3 = {c: 3};

const tar = {};

Object.assign(tar, obj, obj2, obj3);
console.log(tar); // { a: 1, b: 2, c: 3 }

2、会替换已有的属性

const obj = {a: 1, b: 1},
obj2 = {b: 2, c: 2},
obj3 = {c: 3};

const tar = {};

Object.assign(tar, obj, obj2, obj3);
console.log(tar); // { a: 1, b: 2, c: 3 }

3、参数

第一个参数

  1. undefined或null没有包装类,无法转换为对象

Object.assign(null, {a: 1}); // 报错
Object.assign(undefined, {a: 1}); // 报错

  1. number|string|boolean会转换为对应的包装类

let res = Object.assign({a: 1}); // {a: 1}

let res2 = Object.assign(1, {a: 1}); // Number{1, {a: 1}}

let res3 = Object.assign(‘’, {a: 1}); // String{‘’, {a: 1}}

let res4 = Object.assign(true, {a: 1}); // Boolean{a: 1}

第二个参数

  1. 第二个参数传undefined|null不会进行任何处理

let res = Object.assign({a: 1}, undefined); // {a: 1}

let res2 = Object.assign({a: 1}, null); // {a: 1}

  1. 第二个参数如果不可可枚举的,不会进行处理

let res = Object.assign({a: 1}, 1); // {a: 1}

let res2 = Object.assign({a: 1}, true); // {a: 1}

  1. 第二个参数如果是可枚举的,才会进行拷贝

let res = Object.assign({a: 1}, ‘1’); // {a: 1, 0: ‘1’}

let res2 = Object.assign({a: 1}, ‘abc’); // {a: 1, 0: ‘a’, 1: ‘b’, 2: ‘c’}

第二个参数的本质

const str = ‘abc’, // 会通过new String()转换为类数组
bool = true, // 通过new Boolean()转换成[[PrimitiveValue]]的属性,他是不能遍历的
num = 10; // 同bool

const res = Object.assign({}, str, bool, num);

console.log(res); // { ‘0’: ‘a’, ‘1’: ‘b’, ‘2’: ‘c’ }

4、不可合并继承属性跟不可枚举的属性

// Object.create创建一个以{foo: 1}为原型的对象
const obj = Object.create({foo: 1}, {
bar: {
value: 2
},

baz: {
value: 3,
enumerable: true
}
});

const copy = Object.assign({}, obj);
console.log(copy); // {baz: 3}

5、原始类型Symbol()值也可以通过assign拷贝

● 生成永远不会重复的东西

let a = Symbol(‘1’),
b = Symbol(‘1’);

console.log(a, b); // Symbol(1) Symbol(1)
console.log(a === b, a == b); // false false

var test = Object.assign({a: 1}, {
[Symbol(‘b’)]: 2
});

console.log(test); // {a: 1, Symbol(b): 2}

6、assign是浅拷贝

● 只拷贝值,不拷贝地址为浅拷贝

const obj = {
a: {
b: 1
}
};

const obj2 = Object.assign({}, obj);

obj.a.b = 2;

console.log(obj); // b跟着修改为2

7、assign同名属性的替换

const obj = {
a: {
b: 1
}
};

const source = {
a: {
c: 2
}
}

const obj2 = Object.assign(obj, source);

console.log(obj); // 同名属性a跟着修改

8、assign数组的拷贝

● 根据同名属性进行替换

// 根据数组下标来进行替换
const arr = Object.assign([1, 2, 3], [4, 5]);

console.log(arr); // [4, 5, 3]

9、取值属性get的拷贝

● 不会将整个取值函数拷贝

const source = {
get foo() {
return 1;
}
};

const obj = {};

Object.assign(obj, source);

console.log(obj); // {foo: 1}

10、在原型上扩充方法跟属性

let age = 20;
function Person() {}

Object.assign(Person.prototype, {
eat() {},
age
});

console.log(Person.prototype); // {age: 20, eat: ƒ, constructor: ƒ}

11、使用assign合并配置默认项

// 当用户没有配置,那么使用默认配置,用户配置即使用该配置

const Default = {
url: {
Post: ‘www.baidu.com’
}
};

function test(option) {
option = Object.assign({}, Default, option);
}

test(); // {url: {Post: ‘www.baidu.com’}}

test({
url: {
Post: ‘6666’
}
}); // {url: {Post: ‘6666’}}

五、定义对象的多个属性

1、Object.defineProperties()

● 定义一个对象的多个属性
● 两个参数
a. 目标对象
b. 多个对象

const obj = {};

Object.defineProperties(obj, {
a: {
value: 1,
writable: true
},
b: {
value: 2
}
});

console.log(obj); // {a: 1, b: 2}

2、Object.getOwnPropertyDescriptors()

● 获取对象的多个属性的描述符

console.log(Object.getOwnPropertyDescriptors(obj));
// {
// “a”: {
// “value”: 1,
// “writable”: true,
// “enumerable”: false,
// “configurable”: false
// },
// “b”: {
// “value”: 2,
// “writable”: false,
// “enumerable”: false,
// “configurable”: false
// }
// }

3、set赋值函数的拷贝

使用Object.assign()是不可以拿到set赋值函数的

const course = {
set foo(value) {
console.log(value);
}
};

const tar = {};

Object.assign(tar, course);
console.log(tar); // {foo: undefined}

set赋值函数的拷贝

● 唯一实现方法

const course = {
set foo(value) {
console.log(value);
}
};

const tar = {};

Object.defineProperties(tar, Object.getOwnPropertyDescriptors(course));

console.log(Object.getOwnPropertyDescriptor(tar, ‘foo’)); // {get: undefined, enumerable: true, configurable: true, set: ƒ}

4、浅拷贝对象(克隆对象)

Object.getPrototypeOf()获取对象的原型

const obj = {
a: 1,
b: {
c: 2
}
}

const clone = (obj) => Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));

console.log(clone(obj));
// {
// a: 1,
// b: {
// c: 2
// }
// }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/387429
推荐阅读
相关标签
  

闽ICP备14008679号