直接访问原型的现代方法
Object.create(proto, [descriptors]) (ES5)
一、Object.create(proto, [descriptors])—— 利用给定的proto作为[[Prototype]]和可选的属性描述来创建一个空对象。
二、Object.create有一个可选的第二参数:属性描述器。我们可以在此处为新对象提供额外的属性,就像这样:
let animal = {
eats: true
};
let rabbit = Object.create(animal, {
jumps: {
value: true
}
});
alert(rabbit.jumps); // true
创建对象
一、该方法主要用于创建一个新对象,并为其设置原型,用(上述)属性描述符来定义对象的原型属性。
var parent = {hi: 'Hello'};
var o = Object.create(parent, {
prop: {
value: 1
}
});
o.hi; // 'Hello'
// 获得它的原型
Object.getPrototypeOf(parent) === Object.prototype; // true 说明parent的原型是Object.prototype
Object.getPrototypeOf(o); // {hi: "Hello"} // 说明o的原型是{hi: "Hello"}
o.hasOwnProperty('hi'); // false 说明hi是原型上的
o.hasOwnProperty('prop'); // true 说明prop是原型上的自身上的属性。
创建空白对象
一、我们可以用它来创建一个完全空白的对象,这样的事情在ES3中可是做不到的。
var o = Object.create(null);
typeof o.toString(); // 'undefined'
克隆对象
一、Object.create提供了一种简单的方式来浅拷贝一个对象的所有描述符:
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
1、此调用可以对obj进行真正准确地拷贝,包括所有的属性:可枚举和不可枚举的,数据属性和 setters/getters —— 包括所有内容,并带有正确的[[Prototype]]。
Object.getPrototypeOf(obj)
一、返回对象obj的[[Prototype]](与proto的 getter 相同)。
Object.setPrototypeOf(obj, proto)
将对象obj的[[Prototype]]设置为proto(与proto的 setter 相同)。
Object.keys,values,entries
一、对于普通对象,下列这些方法是可用的:
- Object.keys(obj):返回一个包含该对象所有的键的数组。
- Object.values(obj): 返回一个包含该对象所有的值的数组。
- Object.entries(obj):返回一个包含该对象所有 [key, value] 键值对的数组。
二、但是注意区别(比如说跟 map 的区别):
Map | Object | |
---|---|---|
调用语法 | map.keys() | Object.keys(obj),而不是obj.keys() |
返回值 | 可迭代项 | “真正的”数组 |
1、第一个区别是,对于对象我们使用的调用语法是Object.keys(obj),而不是obj.keys()。
(1)为什么会这样?主要原因是灵活性。
① 在 JavaScript 中,对象是所有复杂结构的基础。
② 因此,我们可能有一个自己创建的对象,比如data,并实现了它自己的data.values()方法。同时,我们依然可以对它调用Object.values(data)方法。
2、第二个区别是Object.*方法返回的是“真正的”数组对象,而不只是一个可迭代项。这主要是历史原因。
举个例子:
let user = {
name: "John",
age: 30
};
// 将下面的值console.log()出来
Object.keys(user) // ["name", "age"]
Object.values(user) // ["John", 30]
Object.entries(user) // [ ["name","John"], ["age",30] ]
【示例1】使用Object.values来遍历属性值
let user = {
name: "John",
age: 30
};
// 遍历所有的值
for (let value of Object.values(user)) {
alert(value); // John, then 30
}
三、Object.keys/values/entries 会忽略 symbol 属性
1、就像for..in循环一样,这些方法会忽略使用Symbol(…)作为键的属性。
2、通常这很方便。但是,如果我们也想要 Symbol 类型的键:
① 那么这儿有一个单独的方法Object.getOwnPropertySymbols,它会返回一个只包含 Symbol 类型的键的数组。
② 另外,还有一种方法Reflect.ownKeys(obj),它会返回所有键。
四、所有返回对象属性的方法(如Object.keys及其他,都只返回“自身”的属性,都会忽略继承的属性。
1、它们只会对对象自身进行操作。不考虑继承自原型的属性。
2、如果我们想继承它们,我们可以使用for…in。
转换对象
一、对象缺少数组存在的许多方法,例如map和filter等。
二、如果我们想应用它们,那么我们可以使用Object.entries,然后使用Object.fromEntries:
- 使用Object.entries(obj)从obj获取由键/值对组成的数组。
- 对该数组使用数组方法,例如map。
- 对结果数组使用Object.fromEntries(array)方法,将结果转回成对象。
【示例1】我们有一个带有价格的对象,并想将它们加倍:
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let doublePrices = Object.fromEntries(
// 转换为数组,之后使用 map 方法,然后通过 fromEntries 再转回到对象
Object.entries(prices).map(([key, value]) => [key, value * 2])
);
alert(doublePrices.meat); // 8
Object.getOwnPropertySymbols(obj)
一、返回一个由自身所有的 symbol 类型的键组成的数组。
Object.getOwnPropertyNames(obj)
Reflect.ownKeys(obj)
Object.prototype.hasOwnProperty(propName) / obj.hasOwnProperty(key)
一、语法
object.hasOwnProperty(proName)
- 参数object是必选项。一个对象的实例。
- proName是必选项。一个属性名称的字符串值
二、如果obj拥有名为key的自身的属性(非继承而来的),则返回true。当该属性是从原型链中继承而来或者根本不存在时,返回false
1、此方法无法检查该对象的原型链中是否具有该属性。
| 【示例】```javascript var o = {prop:1}; o.hasOwnProperty(‘prop’); // true o.hasOwnProperty(‘toString’); // false o.hasOwnProperty(‘formString’); // false
|
| --- |
| 【示例】antd的Input.Search,点击搜索图标、清除图标、按下回车键时都会触发onSearch事件,这时可以根据事件类型做不同的处理。<br />1、直接打印event.type,都是click。查看控制台发现点击搜索图标的event.type是继承来的<br />2、Object.keys()打印出不同类型的自身属性```javascript
console.log(Object.keys(event))
// 点击清空
["target", "currentTarget"]
// 点击搜索
["_reactName", "_targetInst", "type", "nativeEvent", "target", "currentTarget", "eventPhase", "bubbles", "cancelable", "timeStamp", "defaultPrevented", "isTrusted", "view", "detail", "screenX", "screenY", "clientX", "clientY", "pageX", "pageY", "ctrlKey", "shiftKey", "altKey", "metaKey", "getModifierState", "button", "buttons", "relatedTarget", "movementX", "movementY", "isDefaultPrevented", "isPropagationStopped"]
// 按下回车
["_reactName", "_targetInst", "type", "nativeEvent", "target", "currentTarget", "eventPhase", "bubbles", "cancelable", "timeStamp", "defaultPrevented", "isTrusted", "view", "detail", "key", "code", "location", "ctrlKey", "shiftKey", "altKey", "metaKey", "repeat", "locale", "getModifierState", "charCode", "keyCode", "which", "isDefaultPrevented", "isPropagationStopped"]
3、发现点击搜索图标、按下回车键有自身的type属性,所以可以根据这点来满足需求:如果内容为空,则提示```javascript const onSearch = (value, event) => { console.log(‘event:’, event) console.log(‘event.type:’, event.type) console.log(‘event,hasOwnProperty:’, event.hasOwnProperty(‘type’)); console.log(‘event,keys:’, Object.keys(event));
if (!value) { if (event.hasOwnProperty(‘type’)) { message.error(‘请输入类目名称’) } return; } // changeItem(value); }; ``` | | —- |
Object.is()
见比较运算符#Object.is():https://www.yuque.com/tqpuuk/yrrefz/wza8dh#D516R