diff --git a/docs/object.md b/docs/object.md index 97240c3..8ac6d75 100644 --- a/docs/object.md +++ b/docs/object.md @@ -669,7 +669,7 @@ Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 }) ## `__proto__`属性,Object.setPrototypeOf(),Object.getPrototypeOf() -**(1)`__proto__`属性** +### `__proto__`属性 `__proto__`属性(前后各两个下划线),用来读取或设置当前对象的`prototype`对象。目前,所有浏览器(包括 IE11)都部署了这个属性。 @@ -723,9 +723,9 @@ Object.getPrototypeOf({ __proto__: null }) // null ``` -**(2)Object.setPrototypeOf()** +### Object.setPrototypeOf() -`Object.setPrototypeOf`方法的作用与`__proto__`相同,用来设置一个对象的`prototype`对象。它是ES6正式推荐的设置原型对象的方法。 +`Object.setPrototypeOf`方法的作用与`__proto__`相同,用来设置一个对象的`prototype`对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。 ```javascript // 格式 @@ -759,11 +759,29 @@ obj.y // 20 obj.z // 40 ``` -上面代码将proto对象设为obj对象的原型,所以从obj对象可以读取proto对象的属性。 +上面代码将`proto`对象设为`obj`对象的原型,所以从`obj`对象可以读取`proto`对象的属性。 -**(3)Object.getPrototypeOf()** +如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。 -该方法与setPrototypeOf方法配套,用于读取一个对象的prototype对象。 +```javascript +Object.setPrototypeOf(1, {}) === 1 // true +Object.setPrototypeOf('foo', {}) === 'foo' // true +Object.setPrototypeOf(true, {}) === true // true +``` + +由于`undefined`和`null`无法转为对象,所以如果第一个参数是`undefined`或`null`,就会报错。 + +```javascript +Object.setPrototypeOf(undefined, {}) +// TypeError: Object.setPrototypeOf called on null or undefined + +Object.setPrototypeOf(null, {}) +// TypeError: Object.setPrototypeOf called on null or undefined +``` + +### Object.getPrototypeOf() + +该方法与`Object.setPrototypeOf`方法配套,用于读取一个对象的原型对象。 ```javascript Object.getPrototypeOf(obj); @@ -773,6 +791,7 @@ Object.getPrototypeOf(obj); ```javascript function Rectangle() { + // ... } var rec = new Rectangle(); @@ -785,6 +804,36 @@ Object.getPrototypeOf(rec) === Rectangle.prototype // false ``` +如果参数不是对象,会被自动转为对象。 + +```javascript +// 等同于 Object.getPrototypeOf(Number(1)) +Object.getPrototypeOf(1) +// Number {[[PrimitiveValue]]: 0} + +// 等同于 Object.getPrototypeOf(String('foo')) +Object.getPrototypeOf('foo') +// String {length: 0, [[PrimitiveValue]]: ""} + +// 等同于 Object.getPrototypeOf(Boolean(true)) +Object.getPrototypeOf(true) +// Boolean {[[PrimitiveValue]]: false} + +Object.getPrototypeOf(1) === Number.prototype // true +Object.getPrototypeOf('foo') === String.prototype // true +Object.getPrototypeOf(true) === Boolean.prototype // true +``` + +如果参数是`undefined`或`null`,它们无法转为对象,所以会报错。 + +```javascript +Object.getPrototypeOf(null) +// TypeError: Cannot convert undefined or null to object + +Object.getPrototypeOf(undefined) +// TypeError: Cannot convert undefined or null to object +``` + ## Object.keys(),Object.values(),Object.entries() ### Object.keys() @@ -1325,7 +1374,7 @@ const firstName = message?.body?.user?.firstName || 'default'; ```javascript // 如果 a 是 null 或 undefined, 返回 undefined -// 否则返回 a?.b.c().d +// 否则返回 a.b.c().d a?.b.c().d // 如果 a 是 null 或 undefined,下面的语句不产生任何效果 diff --git a/docs/reflect.md b/docs/reflect.md index 9113c7f..ed9b028 100644 --- a/docs/reflect.md +++ b/docs/reflect.md @@ -257,16 +257,16 @@ Object.getPrototypeOf(myObj) === FancyThing.prototype; Reflect.getPrototypeOf(myObj) === FancyThing.prototype; ``` -`Reflect.getPrototypeOf`和`Object.getPrototypeOf`的一个区别是,如果第一个参数不是对象(包括`null`和`undefined`),`Object.getPrototypeOf`会将这个参数转为对象,然后再运行,而`Reflect.getPrototypeOf`会报错。 +`Reflect.getPrototypeOf`和`Object.getPrototypeOf`的一个区别是,如果参数不是对象,`Object.getPrototypeOf`会将这个参数转为对象,然后再运行,而`Reflect.getPrototypeOf`会报错。 ```javascript -Object.getPrototypeOf(1) // undefined +Object.getPrototypeOf(1) // Number {[[PrimitiveValue]]: 0} Reflect.getPrototypeOf(1) // 报错 ``` ### Reflect.setPrototypeOf(obj, newProto) -`Reflect.setPrototypeOf`方法用于设置对象的`__proto__`属性,对应`Object.setPrototypeOf(obj, newProto)`。 +`Reflect.setPrototypeOf`方法用于设置对象的`__proto__`属性,返回第一个参数对象,对应`Object.setPrototypeOf(obj, newProto)`。 ```javascript const myObj = new FancyThing(); @@ -278,11 +278,24 @@ Object.setPrototypeOf(myObj, OtherThing.prototype); Reflect.setPrototypeOf(myObj, OtherThing.prototype); ``` -如果第一个参数不是对象,`Reflect.setPrototypeOf`和`Object.setPrototypeOf`都会报错。 +如果第一个参数不是对象,`Object.setPrototypeOf`会返回第一个参数本身,而`Reflect.setPrototypeOf`会报错。 ```javascript -Object.setPrototypeOf(1) // 报错 -Reflect.setPrototypeOf(1) // 报错 +Object.setPrototypeOf(1, {}) +// 1 + +Reflect.setPrototypeOf(1, {}) +// TypeError: Reflect.setPrototypeOf called on non-object +``` + +如果第一个参数是`undefined`或`null`,`Object.setPrototypeOf`和`Reflect.setPrototypeOf`都会报错。 + +```javascript +Object.setPrototypeOf(null, {}) +// TypeError: Object.setPrototypeOf called on null or undefined + +Reflect.setPrototypeOf(null, {}) +// TypeError: Reflect.setPrototypeOf called on non-object ``` ### Reflect.apply(func, thisArg, args)