ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021.04.27(super 关键字、对象的扩展运算符)

2021-04-27 16:02:52  阅读:171  来源: 互联网

标签:... 27 obj 2021.04 对象 解构 运算符 foo super


super 关键字

我们知道, this  关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键
字 super  ,指向当前对象的原型对象。

1.  const proto = {
2.  foo: 'hello'
3.  };
4.
5.  const obj = {
6.  foo: 'world',
7.  find() {
8.  return super.foo;
9.  }
10.  };
11.
12.  Object.setPrototypeOf(obj, proto);
13.  obj.find() // "hello"

上面代码中,对象 obj.find()  方法之中,通过 super.foo  引用了原型对象 proto  的 foo  属
性。

注意, super  关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。

1.  // 报错
2.  const obj = {
3.  foo: super.foo
4.  }
5.
6.  // 报错
7.  const obj = {
8.  foo: () => super.foo
9.  }
10.
11.  // 报错
12.  const obj = {
13.  foo: function () {
14.  return super.foo
15.  }
16.  }

上面三种 super  的用法都会报错,因为对于 JavaScript 引擎来说,这里的 super  都没有用在
对象的方法之中。第一种写法是 super  用在属性里面,第二种和第三种写法是 super  用在一个函
数里面,然后赋值给 foo  属性。目前,只有对象方法的简写法可以让 JavaScript 引擎确认,定
义的是对象的方法。

JavaScript 引擎内部, super.foo  等同于 Object.getPrototypeOf(this).foo  (属性)
或 Object.getPrototypeOf(this).foo.call(this)  (方法)。

1.  const proto = {
2.  x: 'hello',
3.  foo() {
4.  console.log(this.x);
5.  },
6.  };
7.
8.  const obj = {
9.  x: 'world',
10.  foo() {
11.  super.foo();
12.  }
13.  }
14.
15.  Object.setPrototypeOf(obj, proto);
16.
17.  obj.foo() // "world"

上面代码中, super.foo  指向原型对象 proto  的 foo  方法,但是绑定的 this  却还是当前对
象 obj  ,因此输出的就是 world  。

对象的扩展运算符

《数组的扩展》一章中,已经介绍过扩展运算符( ...  )。ES2018 将这个运算符引入了对象。

解构赋值

对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历的(enumerable)、但尚
未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。

1.  let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
2.  x // 1
3.  y // 2
4.  z // { a: 3, b: 4 }

上面代码中,变量 z  是解构赋值所在的对象。它获取等号右边的所有尚未读取的键
( a  和 b  ),将它们连同值一起拷贝过来。

由于解构赋值要求等号右边是一个对象,所以如果等号右边是 undefined  或 null  ,就会报错,因
为它们无法转为对象。

1.  let { ...z } = null; // 运行时错误
2.  let { ...z } = undefined; // 运行时错误

解构赋值必须是最后一个参数,否则会报错。

1.  let { ...x, y, z } = someObject; // 句法错误
2.  let { x, ...y, ...z } = someObject; // 句法错误

上面代码中,解构赋值不是最后一个参数,所以会报错。

注意,解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构
赋值拷贝的是这个值的引用,而不是这个值的副本。

1.  let obj = { a: { b: 1 } };
2.  let { ...x } = obj;
3.  obj.a.b = 2;
4.  x.a.b // 2

上面代码中, x  是解构赋值所在的对象,拷贝了对象 obj  的 a  属性。 a  属性引用了一个对
象,修改这个对象的值,会影响到解构赋值对它的引用。

解构赋值的一个用处,是扩展某个函数的参数,引入其他操作。

1.  function baseFunction({ a, b }) {
2.  // ...
3.  }
4.  function wrapperFunction({ x, y, ...restConfig }) {
5.  // 使用 x 和 y 参数进行操作
6.  // 其余参数传给原始函数
7.  return baseFunction(restConfig);
8.  }

上面代码中,原始函数 baseFunction  接受 a  和 b  作为参数,函
数 wrapperFunction  在 baseFunction  的基础上进行了扩展,能够接受多余的参数,并且保留原
始函数的行为。

扩展运算符

对象的扩展运算符( ...  )用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

1.  let z = { a: 3, b: 4 };
2.  let n = { ...z };
3.  n // { a: 3, b: 4 }

由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组。

1.  let foo = { ...['a', 'b', 'c'] };
2.  foo
3.  // {0: "a", 1: "b", 2: "c"}

如果扩展运算符后面是一个空对象,则没有任何效果。

1.  {...{}, a: 1}
2.  // { a: 1 }

如果扩展运算符后面不是对象,则会自动将其转为对象。

1.  // 等同于 {...Object(1)}
2.  {...1} // {}

上面代码中,扩展运算符后面是整数 1  ,会自动转为数值的包装对象 Number{1}  。由于该对象没
有自身属性,所以返回一个空对象。

 

2021-04-27  15:41:34

标签:...,27,obj,2021.04,对象,解构,运算符,foo,super
来源: https://www.cnblogs.com/zhenggc99/p/14709256.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有