JavaScript中的Object.assign与Getter,Setters 和 definePropert使用

本文介绍关于JavaScript中操作元素对象的Object.assign与Getter,Setters ,definePropert方法。通过对这些概念的理解,能帮助大家更好的理解在JavaScript中项目开发中我们是如何使用这些概念。这些基础概念也是现代JavaScript开发中必知必会的知识点,掌握它们对提供项目代码质量有很大的帮助。

  • Object.assign 使用
  • Getter,Setters 和 definePropert
    • Getter 设置
    • Setters设置值
    • Object.defineProperty 方法

JavaScript 特性 Promise 函数
JavaScript 特性 map、forEach、filter 和 find 与箭头函数的使用
JavaScript 特性 Destructuring 语法
JavaScript 特性 Proxy(代理)和Reflect(反射)
JavaScript 特性 Object.assign与Getter,Setters 和 definePropert
JavaScript 中使用 XMLHttpRequest

Object.assign 使用

  在使用JavaScript编写应用程序代码时,经常会遇到需要合并两个对象的情况。使用Object.assign可以轻松地合并(整合)对象。在合并对象时,如果两个对象具有相同的属性,则可以覆盖其值。此外,Object.assign不仅用于覆盖对象,还可用于复制对象。由于Object.assign是经常用于输入表单等场景的功能,因此必须理解其可以执行的操作。我们将介绍关于Object.assign的基本操作,并使用保持表单值的例子进行了说明。通过查看示例,可以更加直观地感受到该函数在合并对象方面的实际应用,使其变得更加亲近。
通过Object.assign 函数合并两个对象,看看合并时会发生什么。

const target = { a: 1, b: 2}
const source = { c: 3, d: 4}
const returnedTarget = Object.assign(target, source);
console.log(target)
console.log(source)
console.log(returnedTarget)
========= 结果打印 ========

{ a: 1, b: 2, c: 3, d: 4 }
{ c: 3, d: 4 }
{ a: 1, b: 2, c: 3, d: 4 }

运行它会导致:Object.assign 的第一个参数target与第二个参数source合并,但source的内容保持不变。另外,可以看到合并后的对象包含在Object.assign的返回值的returnedTarget中。

可以看到Object.assign的返回值为target,returnedTarget等于target。

1 相同的属性的合并

如果目标对象(target)和源对象(source)都有一个名为"b"的相同属性,则在使用Object.assign时,源对象的属性值将覆盖目标对象的属性值。也就是说,目标对象中的"b"属性将被源对象中的"b"属性覆盖,最终的结果将包含源对象的"b"属性值。

const target = { a: 1, b: 2}
const source = { b: 3, d: 4}
const returnedTarget = Object.assign(target, source);
console.log(target)
console.log(source)
console.log(returnedTarget)
========= 结果打印 ========
{ a: 1, b: 3, d: 4 }
{ b: 3, d: 4 }
{ a: 1, b: 3, d: 4 }

2 更新对象数组的元素

使用 Object.assign可以将元素对象中的属性值进行替换。

let user = [
	{
		name : 'zht',
		dept: '部门一'
	},
	{
		name : 'kaimi',
		dept: '部门二'
	},
];

let user1 = {
	name: '张**',
	dept: '部门一'
}
const returnedTarget = Object.assign(user[1], user1);
console.log(user)
========= 结果打印 ========
[
    {
        "name": "zht",
        "dept": "部门一"
    },
    {
        "name": "张**",
        "dept": "部门一"
    }
]

3 对象的复制

Object.assign也经常用于对象的复制。通过将空对象作为第一个参数,可以创建一个全新的名为"user_clone"的对象。新对象中的属性值将从源对象中复制过来。

let user = [
	{
		name : 'zht',
		dept: '部门一'
	},
	{
		name : 'kaimi',
		dept: '部门二'
	},
];
const returnedTarget = Object.assign({}, user);
console.log(returnedTarget)
========= 结果打印 ========
{
    "0": {
        "name": "zht",
        "dept": "部门一"
    },
    "1": {
        "name": "kaimi",
        "dept": "部门二"
    }
}

4 多个参数

上面的例子Object.assign 只有两个参数,但是Object.assign函数可以接受多个参数来进行合并。

let user = {
  name: "zht",
};

let user_id = {
  id: 1,
};

let dept = {
  dpet: "部门一",
};
user = Object.assign(user, user_id, dept);
console.log(user);
========= 结果打印 ========
{
    "name": "zht",
    "id": 1,
    "dpet": "部门一"
}

如果合并的对象包含了相同键的属性和值,它们会按程序的执行顺序被替换,最后的对象会覆盖前边的对象。

let user = {
  id: 0,
};

let user_id_1 = {
  id: 1,
};

let user_id_2 = {
  id: 2,
};

let user_id_3 = {
  id: 3,
};
user = Object.assign(user, user_id_1, user_id_2, user_id_3);
console.log(user);
========= 结果打印 ========
    3

5 Object.assign (form) 的例子

Object.assign经常用于表单提交时,在下面的代码中,我们将举例说明如何在保留输入表单值的form对象中使用。首先,准备form对象,它具有name和dept两个属性,初始值都为null。

如果输入表单有值,我们用input对象来接收它。如果要用input对象来覆盖form对象,则可以使用Object.assign并按如下方式编写代码来覆盖name的值。

const form = {
	name: null,
	dpet: null
}
const input = {
	name: 'zht'
}
Object.assign(form, input)

我们写一个与前面不同的例子,在表单元素有点复杂的时候,可以通过使用 Object.assign 来简化代码。比如要一次更新7个属性中的3个,可以使用Object.assign只覆盖3个值。

const form = {
	name: null,
	dept: null,
	id: null,
	post: null,
	address: null,
	phone: null
}

const input = {
	name: 'zht',
	dept: '部门一',
	id: 1
}
Object.assign(form, input)
console.log(form)
========= 结果打印 ========
{
    "name": "zht",
    "dept": "部门一",
    "id": 1,
    "post": null,
    "address": null,
    "phone": null
}

还可以进行更为复杂的嵌套结构合并,下面我们将地址address属性设置成一个数据对象来进行合并。

const form = {
	name: null,
	dept: null,
	id: null,
	post: null,
	address: null,
	phone: null
}
const input = {
	name: 'zht',
	dept: '部门一',
	id: 1
}
Object.assign(form, input)
const address = {
	address : {
		address_1: '地址1',
		address_2: '地址2',
	    address_3: '地址3',
	}
}
Object.assign(form, address);
console.log(form)
========= 结果打印 ========
{
    "name": "zht",
    "dept": "部门一",
    "id": 1,
    "post": null,
    "address": {
        "address_1": "地址1",
        "address_2": "地址2",
        "address_3": "地址3"
    },
    "phone": null
}

Getter,Setters 和 definePropert

  下面我们介绍一下JavaScript中的Getter和Setter以及Object.defineProperty。即使大家没有机会在项目代码中自己使用到它们,但是当你阅读库代码,源码或文档时也会经常看到它们。很多时候我们在编码的时候不会使用到它们,对它们的理解还不是很清晰,希望能通过这篇文章让大家能对Getter,Setters 和 definePropert有所了解。

Getter 设置

  我们先创建一个数据对象,在数据对象中创建一个fullName方法,它用于返回名称与部门名称。在使用fullName 方法的时候,需要user对象使用这样的语法fullName(),才可以引用到fullName。

let user = {
  name: "zht",
  dept: "部门一",
  fullName: function () {
    return `${this.name}${this.dept} 员工`;
  },
};
alert(user.fullName());

现在我们来使用Getter来重新描述user对象中的fullName方法,很多人第一次看到怎么使用会觉得奇怪,竟然可以这样定义方法。

let user = {
  name: "zht",
  dept: "部门一",
  get fullName() {
    return `${this.name}${this.dept} 员工`;
  },
};
alert(user.fullName);

与上一个例子中的引用方法不同了,执行时不需要括号,可以像访问name和dept的属性时一样直接引用了。

通过将方法定义为 Getters,它同时也可以使用 [] 括号而不是 .(点)来访问它。

let user = {
  name: "zht",
  dept: "部门一",
  get fullName() {
    return `${this.name}${this.dept} 员工`;
  },
};
alert(user["fullName"]);

Setters设置值

  Setter是一种特殊的函数,用于设置对象的属性值。它可以被用于控制属性的赋值过程,从而可以实现更加灵活的属性访问和修改。Setter函数的命名规则以"set"为前缀,后面跟着要设置的属性名。Setter函数可以接受一个参数,用于设置属性的值

下面的例子中"set fullName",我们尝试为user对象的fullName方法设置一个赋值功能,如果fullName具有Setter函数,则Setter函数会被自动调用,并将参数作为值传递给函数,从而完成其他的业务处理。

let user = {
  name: "zht",
  dept: "部门一",
  get fullName() {
    return `${this.name}${this.dept} 员工`;
  },
  set fullName(value) {
    [this.name, this.dept] = value.split(" ");
  },
};
//setter
user.fullName = "kaimi 部门二";
//getter
alert(user["fullName"]);
========= 结果打印 ========
kaimi是部门二 员工

在get和set中使用了相同的fullName属性,但在使用等号“=”进行赋值时setter被使用,而在获取值时则使用getter。

在setter中,也可以进行输入字符串的检查。可以使用match方法检查输入的字符串中是否有空格,如果没有空格,则输出消息。

let user = {
  name: "zht",
  dept: "部门一",
  get fullName() {
    return `${this.name}${this.dept} 员工`;
  },
  set fullName(value) {
   if (!value.match(" ")) {
      alert("字符串中没有空格");
      return;
    }
    [this.name, this.dept] = value.split(" ");
  },
};
user.fullName = "kaimi部门二";
alert(user["fullName"]);
========= 结果打印 ========
字符串中没有空格
zht是部门一 员工

Object.defineProperty 方法

  通过使用 Object.defineProperty,可以向已定义的 user 对象添加 Getter 和 Setter。虽然从名称和格式中可以推断出 Object.defineProperty 的用途,但如果已经理解了 Getter 和 Setter,那么使用它就不会太困难了。

下面的代码示例中,使用 Object.defineProperty 向已定义的 user 对象添加 Setter 和 Getter。

let user = {
  name: "zht",
  dept: "部门一"
};
Object.defineProperty(user, "fullName", {
  get: function () {
       return `${this.name}${this.dept} 员工`;
  },
  set: function (value) {
    [this.name, this.dept] = value.split(" ");
  },
});
user.fullName = "kaimi 部门二";
alert(user["fullName"]);
========= 结果打印 ========
kaimi是部门二 员工

Object.defineProperty 的格式如下。

  • Object.defineProperty(对象,属性名,描述)

上面的例子中,user对象中属性名对应访问时使用的属性名的fullName,描述符对应有get和set的对象。

在Object.defineProperty中有两个重要的属性。

  • enumerable (set get)方法开关。
  • configurable delete删除是否可以使用。

Object.defineProperty中的get和set方法,我们可以通过配置设置enumerable属性的 true 或 false来控制它们的会不会被使用。通过将其设置为 true 或 false 来检查存在何种差异。默认情况下 enumerable 为 false,但您可以像这样显式设置它:

let user = {
  name: "zht",
  dept: "部门一"
};
Object.defineProperty(user, "fullName", {
  get: function () {
       return `${this.name}${this.dept} 员工`;
  },
  set: function (value) {
    [this.name, this.dept] = value.split(" ");
  },
  enumerable: true
});
//使用 for 循环显示由 Object.defineProperty中的元素。
for (key in user) {
  console.log(key);
}
========= 结果打印 ========
{ firstName: 'zht', lastName: '部门一', fullName: 'zht是部门一 员工' }

将 enumerable 设置为 false 将不会显示 fullName中的内容。

let user = {
  name: "zht",
  dept: "部门一"
};
Object.defineProperty(user, "fullName", {
 ......
  enumerable: false
});
//使用 for 循环显示由 Object.defineProperty中的元素。
for (key in user) {
  console.log(key);
}
========= 结果打印 ========
{ firstName: 'zht', lastName: '部门一'}

它还有一个重要的特性是,在使用 Object.assign 合并对象时,如果被合并的对象 enumerable 为true fullName 将被合并,但如果为false则不会包含在合并中。

// enumerable为true的时候
console.log(Object.assign({}, user));
========= 结果 ========
{ firstName: 'zht', lastName: '部门一', fullName: 'zht是部门一 员工' }

// enumerable为false的时候
console.log(Object.assign({}, user));
========= 结果 ========
{ firstName: 'zht', lastName: '部门一'}

configurable属性是控制对象属性的是否可以执行delete删除命令,使用方法与enumerable一样,默认情况下它为 false。如果设置为true则表示对象中的(set,get)方法可以被delete命令删除,方法被删除后再次调用这些被删除的方法就会返回undefined。如果为false,表示fullName这样的方法不会被delete命令删除。

let user = {
  name: "zht",
  dept: "部门一"
};
Object.defineProperty(user, "fullName", {
  get: function () {
       return `${this.name}${this.dept} 员工`;
  },
  set: function (value) {
    [this.name, this.dept] = value.split(" ");
  },
  enumerable: true,
  configurable: true,
});

//configurable: true的时候
delete user.fullName;
console.log(user.fullName);
========= 结果 ========
undefined

//configurable: false的时候
delete user.fullName;
console.log(user.fullName);
========= 结果 ========
zht是部门一 员工

通过上边的介绍,使您在开发中使用不到它们,但是当这些关键字出现在代码中的时候,您也会更好地理解这些代码是做什么的。希望以后在遇到Getter、Setter、Object.defineProperty这些关键字的代码时候,你不在被它们给困扰了。

你可能感兴趣的:(javascript,javascript,前端,开发语言,node.js)