js对象实例详解(JavaScript对象深度剖析,深度理解(4)

// 属性简写 var foo = 'bar'; var baz = {foo}; baz // {foo: "bar"} // 等同于 var baz = {foo: foo}; // 方法简写 function f(x, y) { return {x, y}; } // 等同于 function f(x, y) { return {x: x, y: y}; } f(1, 2) // Object {x: 1, y: 2}

合并对象:

Object.assign(target, [...source]);

将 source 中所有和枚举的属性复制到 target。

多个 source 对象有同名属性,后面的覆盖前面的。

var target = { a: 1 }; var source1 = { b: 2 }; var source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}

注意一点,该命令执行的是浅克隆,如果 source 中有属性是对象,target 中会复制该对象的引用。

常用于给对象添加属性和方法(如给构造函数的原型添加方法),克隆、合并对象等。

获取对象自身的值或键值对(做为Object.keys(obj)的补充不包括不可枚举的):

Object.keys(obj)返回 obj 自身所有可枚举属性的值组成的数组。

Object.entries(obj)返回 obj 自身所有可枚举键值对数组组成的数组,例如:

var obj = { foo: 'bar', baz: 42 }; Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ] // 可用于将对象转为 Map 结构 var obj = { foo: 'bar', baz: 42 }; var map = new Map(Object.entries(obj)); map // Map { foo: "bar", baz: 42 }

拓展运算符:

取出对象所有可历遍属性,举例:

let z = { a: 3, b: 4 }; let n = { ...z }; n // { a: 3, b: 4 } // 可代替 Object.assign() let ab = { ...a, ...b }; // 等同于 let ab = Object.assign({}, a, b);

可用于解构赋值中最后一个参数:

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; x // 1 y // 2 z // { a: 3, b: 4 } // 可以这样理解,把 z 拆开以后就等于后面对象未被分配出去的键值对。

Null 传导运算符:

const firstName = message?.body?.user?.firstName || 'default'; // 代替 const firstName = (message && message.body && message.body.user && message.body.user.firstName) || 'default';

class:

ES6 引入了 class 关键字,但并没有改变对象基于原型继承的原理,只是一个语法糖,让他长得像传统面向对象语言而已。

以下两个写法完全等价:

function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; //定义类 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } // 类中定义的方法就是在原型上

有两点区别, class 中定义的方法是不可枚举的,class 必须通过 new 调用不能直接运行。

class 不存在变量提升,使用要在定义之后。

class 中的方法前加 static 关键字定义静态方法,只能通过 class 直接调用不能被实例继承。

如果静态方法包含 this 关键字,这个 this 指的是 class,而不是实例。注意下面代码:

class Foo { static bar () { this.baz(); } static baz () { console.log('hello'); } baz () { console.log('world'); } } Foo.bar() // hello

父类的静态方法,可以被子类继承,目前 class 内部无法定义静态属性。

设置静态属性与实例属性新提案:

class 的实例属性可以用等式,写入类的定义之中。

静态属性直接前面加 static 即可。

class MyClass { myProp = 42; static myStaticProp = 42; }

class 的继承:

class 通过 extends 实现继承,注意 super 关键字

class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // 调用父类的constructor(x, y) this.color = color; } toString() { return this.color + ' ' + super.toString(); // 调用父类的toString() } }

extends 可以继承其他类或任何有 prototype 属性的函数。

super 会从父类获取各路信息绑定到子类的 this。

子类自己没有 this 对象,要先继承父类的实例对象然后再进行加工,所以要在 constructor 里调用 super 继承 this 对象后才能使用 this。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyzfgs.html