1.Object.assign()

用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象(一层深度深拷贝)。

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };const returnedTarget = Object.assign(target, source);console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }

2.Object.create()

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)

const person = {isHuman: false,printIntroduction: function () {console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);}
};const me = Object.create(person);me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwrittenme.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"

3.Object.defineProperty()

直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

obj

要在其上定义属性的对象。

prop

要定义或修改的属性的名称。

descriptor

将被定义或修改的属性描述符。

4.Object.entries(obj)

参数obj

可以返回其可枚举属性的键值对的对象。

返回值

给定对象自身可枚举属性的键值对数组。

5.Object.freeze()

冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

const obj = {prop: 42
};Object.freeze(obj);obj.prop = 33;
// Throws an error in strict modeconsole.log(obj.prop);
// expected output: 42

6.Object.fromEntries()

把键值对列表转换为一个对象。

const entries = new Map([['foo', 'bar'],['baz', 42]
]);const obj = Object.fromEntries(entries);console.log(obj);
// expected output: Object { foo: "bar", baz: 42 }

7.Object.getOwnPropertyDescriptor(obj, prop)

返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

参数

obj

需要查找的目标对象

prop

目标对象内属性名称

返回值

如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回 undefined

8.Object.getOwnPropertyNames(obj)

参数

obj

一个对象,其自身的可枚举和不可枚举属性的名称被返回。

返回值

返回自身所有属性(包括不可枚举)对应的字符串数组。for...in会遍历自身和原型链所有可枚举属性,object.key只能遍历自身可枚举属性。

9.Object.getOwnPropertySymbols()

返回一个给定对象自身的所有 Symbol 属性的数组。

参数

obj

要返回 Symbol 属性的对象。

返回值

在给定对象自身上找到的所有 Symbol 属性的数组。

10.Object.getPrototypeOf(object)

返回指定对象的原型(内部[[Prototype]]属性的值)

const prototype1 = {};
const object1 = Object.create(prototype1);console.log(Object.getPrototypeOf(object1) === prototype1);
// expected output: true

11.Object.keys()

返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。

二、reflect

Reflect上面的一些方法并不是专门为对象设计的,比如Reflect.apply方法,它的参数是一个函数,如果使用Object.apply(func)会让人感觉很奇怪。2:用一个单一的全局对象去存储这些方法,能够保持其它的JavaScript代码的整洁、干净。不然的话,这些方法可能是全局的,或者要通过原型来调用。3:将一些命令式的操作如delete,in等使用函数来替代,这样做的目的是为了让代码更加好维护,更容易向下兼容;也避免出现更多的保留字。

Reflect对象有下面这些静态的方法:

Reflect.apply
Reflect.construct
Reflect.defineProperty
Reflect.deleteProperty
Reflect.enumerate // 废弃的
Reflect.get
Reflect.getOwnPropertyDescriptor
Reflect.getPrototypeOf
Reflect.has
Reflect.isExtensible
Reflect.ownKeys
Reflect.preventExtensions
Reflect.set
Reflect.setPrototypeOf

下面我们来一一讲解这些方法,了解这些方法如何使用。

Reflect.apply

Reflect.apply(target, thisArgument, argumentsList)

通过指定的参数列表,来调用函数target。其中,target就是我们的目标函数,thisArgument就是target函数调用的时候绑定的this对象,argumentsList就是函数的参数列表。这个方法与原来ES5的Function.prototype.apply类似,我们来看一下示例:

// 查找一个数字数组里面的最大元素
const arr = [1, 3, 5, 7];
let max;
// ES6
max = Reflect.apply(Math.max, undefined, arr);
console.log(max);  // 7
// ES5
max = Math.max.apply(undefined, arr);
console.log(max); // 7
max = Function.prototype.apply.call(Math.max, undefined, arr);
console.log(max); // 7// 截取字符串的一部分
let str = 'hello, world';
let newStr;
// ES6
newStr = Reflect.apply(String.prototype.slice, str, [2, 8]);
console.log(newStr); // llo, w
// ES5
newStr = str.slice(2, 8);
console.log(newStr); // llo, w
newStr = String.prototype.slice.apply(str, [2, 8]);
console.log(newStr); // llo, w

Reflect.construct

Reflect.construct(target, argumentsList[, newTarget])

使用这个方法,与使用new target(...args)方法类似,相当于提供了一种新的不使用new来调用构造函数的方法;其中,target表示被运行的目标函数,argumentsList调用构造函数传递的参数数组或者伪数组,newTarget参数为构造函数,表示使用Reflect.construct后生成的对象是谁的实例,如果没有传递第三个参数,默认和target一样。

我们可以这样理解,如果没有传递第三个参数,那么target就是唯一的构造函数;但是如果传递了第三个参数,那就表示:我们的实例由两部分组成,实力的属性部分由第一个参数部分生成,实例的方法部分由第三个参数生成。下面我们来实践一下这个方法:

// ES5
function A(name) {console.log('Function A is invoked!');this.name = name || 'dreamapple';
}
A.prototype.getName = function() {console.log(this.name);return this.name;
};function B(age) {console.log('Function B is invoked!');this.age = age || 22;
}
B.prototype.getAge = function() {console.log(this.age);return this.age;
};
// 使用函数A作为构造函数
let a = Reflect.construct(A, ['happy']);
// 使用函数B作为构造函数
let b = Reflect.construct(A, ['happy'], B);
console.log(a);
console.log(b);
a.getName();
b.getAge();console.log('---------');// ES6
class A1 {constructor(name) {console.log('Class A1 is invoked!');this.name = name || 'dreamapple';}getName() {console.log(this.name);return this.name;}
}
class B1 {constructor(age) {console.log('Class B1 is invoked!');this.age = age || 22;}getAge() {console.log(this.age);return this.age;}
}
// 使用A1类作为构造函数
let a1 = Reflect.construct(A1, ['happy']);
// 使用B1类作为构造函数
let b1 = Reflect.construct(A1, ['happy'], B1);
console.log(a1);
console.log(b1);

其中运行的结果如下图:

如果此时,我们在上面代码的输出控制台里面运行下面两个函数,则会报错:

b1.getName();
// VM5221:1 Uncaught TypeError: b1.getName is not a function
//    at <anonymous>:1:4
b.getName();
// VM5253:1 Uncaught TypeError: b.getName is not a function
//    at <anonymous>:1:3

这个结果也验证了我们上面所谈论的内容,Reflect.construct会使用第三个参数来作为构造函数,如果没有第三个参数,默认使用第一个参数作为构造函数。

Reflect.defineProperty

Reflect.defineProperty(target, propertyKey, attributes)

这个方法与Object.defineProperty相似,不过Reflect.defineProperty的返回值是一个Boolean值。target表示要定义属性的对象,propertyKey表示要定义或者修改的属性名字,attributes表示定义或者被修改的属性的属性。下面我们来实践一下这个方法:

let obj = {};
// 对象的属性定义失败
try {Object.defineProperty(null, 'a', {value: 22})
}catch (e) {console.log('define property failed!');
}  // define property failed!// 使用Object.defineProperty成功的定义
let obj1 = Object.defineProperty(obj, 'name', {enumerable: true,value: 'dreamapple'
});
console.log(obj); // { name: 'dreamapple' }
console.log(obj1); // { name: 'dreamapple' }// 这里会返回false 因为我们上面定义name这个属性是不可修改的,
// 然后我们又在这里修改了name属性,所以修改失败返回值为false
let result1 = Reflect.defineProperty(obj, 'name', {configurable: true,enumerable: true,value: 'happy'
});
console.log(result1); // false
let result2 = Reflect.defineProperty(obj, 'age', {configurable: true,enumerable: true,value: 22
});
console.log(result2); // true
console.log(obj); // { name: 'dreamapple', age: 22 }

Reflect.definePropertyObject.defineProperty的用法是相似的,但是如果Object.defineProperty的属性定义失败了,就会抛出一个错误,成功的话就会返回这个对象;Reflect.defineProperty如果定义属性失败的话就会返回false,如果成功定义的话,就会返回true。但是如果使用Reflect.defineProperty函数,它的第一个参数不是对象的话,也会抛出错误。

Reflect.deleteProperty

Reflect.deleteProperty(target, propertyKey)

这个方法用于删除一个对象上的属性,与delete操作符相似;其中target表示要操作的对象,propertyKey表示要删除的属性。这个函数的返回值是一个Boolean值,如果成功的话,返回true;失败的话返回false。下面我们来实践这个方法:

let obj = {name: 'dreamapple',age: 22
};let r1 = Reflect.deleteProperty(obj, 'name');
console.log(r1); // true
let r2 = Reflect.deleteProperty(obj, 'name');
console.log(r2); // true
let r3 = Reflect.deleteProperty(Object.freeze(obj), 'age');
console.log(r3); // false

Reflect.get

Reflect.get(target, propertyKey[, receiver])

这个方法用来读取一个对象的属性,target是目标对象,propertyKey是我们要读取的属性,receiver是可选的,如果propertyKey的getter函数里面有this值,那么receiver就是这个this所代表的上下文。下面我们来实践这个方法:

let obj = {name: 'dreamapple',age: 22,get money() {console.log(`I can tell you my name ${this.name}, but not my money`);return 0}
};
console.log(Reflect.get(obj, 'name')); // dreamapple
console.log(Reflect.get(obj, 'myName')); // undefined
// I can tell you my name dreamapple, but not my money
// 0
console.log(Reflect.get(obj, 'money'));
// I can tell you my name happy, but not my money
// 0
console.log(Reflect.get(obj, 'money', {name: 'happy'}));

Reflect.getOwnPropertyDescriptor

Reflect.getOwnPropertyDescriptor(target, propertyKey)

这个方法与Object.getOwnPropertyDescriptor方法类似,其中target是目标对象,propertyKey是对象的属性,如果这个属性存在属性描述符的话就返回这个属性描述符;如果不存在的话,就返回undefined。下面我们来实践一下这个方法:

let obj = {};Reflect.defineProperty(obj, 'name', {configurable: true,enumerable: true,writable: true,value: 'dreamapple'
});let descriptor = Reflect.getOwnPropertyDescriptor(obj, 'name');
// { value: 'dreamapple',
//   writable: true,
//   enumerable: true,
//   configurable: true
// }
console.log(descriptor);let d1 = Reflect.getOwnPropertyDescriptor(obj, 'age');
console.log(d1); // undefined// 如果第一个参数不是对象
let d2 = Object.getOwnPropertyDescriptor('0', 'name');
console.log(d2); // undefinedtry {let d3 = Reflect.getOwnPropertyDescriptor('0', 'name');console.log(d3);
} catch (e) {console.log('error');
} // error

这个方法与Object.getOwnPropertyDescriptor有一些不同的地方,如果第一个参数不是对象的话,那么Object.getOwnPropertyDescriptor会将这个参数强制转换为对象,而方法 Reflect.getOwnPropertyDescriptor会抛出一个错误。

Reflect.getPrototypeOf

Reflect.getPrototypeOf(target)

这个方法与Object.getPrototypeOf方法是一样的,都是返回一个对象的原型,也就是内部的[[Prototype]]属性的值。下面我们来实践一下这个方法:

// ES5
function A() {}
A.prototype.sayHello = function(){};var a = new A();
var aPrototype = Object.getPrototypeOf(a);
console.log(aPrototype);
// Object
//  constructor: A()
//  sayHello: ()
//  __proto__: Object// ES6
let ap = Reflect.getPrototypeOf(a);
console.log(ap);
// Object
//  constructor: A()
//  sayHello: ()
//  __proto__: Objectconsole.log(ap === aPrototype); // true

从上面的结果中,我们可以看到;对于同一个对象,使用Reflect.getPrototypeOf方法和使用Object.getPrototypeOf方法返回的结果是一致的。这里面还有一些需要注意的事情,如果我们要获取原型的那个值不是一个对象,那么函数Reflect.getPrototypeOf会抛出一个异常;对于给定对象的原型,如果没有继承的属性,则返回null。

Reflect.has

Reflect.has(target, propertyKey)

这个方法相当于ES5的in操作符就是检查一个对象上是否含有特定的属性;我们继续来实践这个方法:

function A(name) {this.name = name || 'dreamapple';
}
A.prototype.getName = function() {return this.name;
};var a = new A();console.log('name' in a); // true
console.log('getName' in a); // truelet r1 = Reflect.has(a, 'name');
let r2 = Reflect.has(a, 'getName');
console.log(r1, r2); // true true

这个函数的返回结果是一个Boolean值,如果存在就返回true,不存在就返回false。当然如果目标对象(target)不是一个对象,那么就会抛出一个异常。

Reflect.isExtensible

Reflect.isExtensible(target)

这个函数检查一个对象是否是可以扩展的,也就是是否可以添加新的属性;和方法Object.isExtensible方法相似。其中,target表示目标对象,如果这个目标对象不是一个对象,那么函数会抛出一个异常;函数的返回值表示这个对象是否可以扩展;如果是true,表示这个对象可以扩展,如果是false,表示这个对象不可以扩展。下面我们来实践这个方法:

let obj = {};
let r1 = Reflect.isExtensible(obj);
console.log(r1); // true
// 密封这个对象
Object.seal(obj);
let r2 = Reflect.isExtensible(obj);
console.log(r2); // false
// 冻结一个对象
let obj1 = Object.freeze({});
let r3 = Reflect.isExtensible(obj1);
console.log(r3); // false
// 阻止一个对象添加新的属性
let obj2 = {};
Object.preventExtensions(obj2);
let r4 = Reflect.isExtensible(obj2);
console.log(r4); // false// Reflect.isExtensible 与 Object.isExtensible的区别
try{Reflect.isExtensible(1);
}catch(e) {// 这里捕获错误console.log(e); // Reflect.isExtensible called on non-object...
}try{Object.isExtensible(1);
}catch(e) {console.log(e);
}

从上面的实践中,我们可以看出;当使用Object.isExtensible函数时,如果目标对象不是一个对象,那么这个函数会把这个值强制转换成对象,从而不会抛出错误;但是使用Reflect.isExtensible方法就会抛出一个错误,因为它要求目标对象必须是一个对象。

Reflect.ownKeys

Reflect.ownKeys(target)

这个函数的作用是,返回由目标对象自身的属性键组成的数组;其中target表示目标对象,如果这个目标对象不是一个对象那么这个函数就会抛出一个异常。这个数组的值等于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)),下面我们来实践这个方法:

let a = Symbol.for('a');
let b = Symbol.for('b');let obj = {[a]: 10,[b]: 20,key1: 30,key2: 40
};let arr1 = Object.getOwnPropertyNames(obj);
console.log(arr1); // [ 'key1', 'key2' ]
let arr2 = Object.getOwnPropertySymbols(obj);
console.log(arr2); // [ Symbol(a), Symbol(b) ]
let arr3 = Reflect.ownKeys(obj);
console.log(arr3); // [ 'key1', 'key2', Symbol(a), Symbol(b) ]

Reflect.preventExtensions

Reflect.preventExtensions(target)

这个方法与Object.preventExtensions方法相似,不同的是对于方法Reflect.preventExtensions,传递的参数必须是一个对象,否则会抛出一个异常;但是对于函数Object.preventExtensions,如果我们传递的值不是一个对象,那么它会强制把这个值转换成一个对象,所以不会抛出异常。这个函数的作用是,阻止新的属性添加到对象中去。

下面我们来实践一下这个方法:

let obj = {};
let r1 = Reflect.isExtensible(obj);
console.log(r1); // true
Reflect.preventExtensions(obj);
let r2 = Reflect.isExtensible(obj);
console.log(r2); // false

Reflect.set

Reflect.set(target, propertyKey, value[, receiver])

这个函数的作用是在一个对象身上设置一个属性,其中target表示我们要操作的对象;propertyKey表示我们要设置的属性名,value表示我们要设置的属性值,receiver表示的是一个this值,如果我们在设置值的时候遇到setter函数,那么这个receiver值表示的就是setter函数中的this值。这个函数会返回一个Boolean值,表示在目标对象上设置属性是否成功。

下面我们来实践一下这个函数:

let obj = {set name(name) {console.log('this: --> ', this);},age: 22
};let r1 = Reflect.set(obj, 'age', 24);
console.log(r1); // true
console.log(obj); // { name: [Setter], age: 24 }console.log('\n');
let r2 = Reflect.set(obj, 'name', 'dreamapple', {test: 'test'}); // this: -->  { test: 'test' }
console.log(r2); // true
console.log(obj); // { name: [Setter], age: 24 }

Reflect.setPrototypeOf

Reflect.setPrototypeOf(target, prototype)

Reflect.setPrototypeOf与Object.setPrototypeOf方法的作用是相似的,设置一个对象的原型,如果设置成功的话,这个对象会返回一个true;如果设置失败,这个对象会返回一个false。下面我们来实践一下这个方法:

let obj = {};
let r1 = Reflect.setPrototypeOf(obj, Object.prototype);
console.log(r1); // true
let r2 = Reflect.setPrototypeOf(Object.freeze({}), null);
console.log(r2); // false

object与reflect相关推荐

  1. es6相关面试题:1.rest参数;2.new.target;3.object.defineProperty与Proxy的区别;4.Reflect对象作用;5.lterator迭代器;6.async

    文章目录 说说对ES6中rest参数的理解 说说你对new.target的理解 谈谈object.defineProperty与Proxy的区别 ES6中的Reflect对象有什么用? 简单介绍下ES ...

  2. 详解Reflect:Reflect和Object的异同,Reflect的一些内置方法以及方法注意点

    Reflect Reflect拥有Object对象的一些内部方法,某些方法会同时在Object对象和Reflect对象上部署,也就是说Object对象上存在的方法,通过Reflect也可以访问到. 单 ...

  3. ES6 之Reflect 与 Proxy概述

    Proxy 与 Reflect 是 ES6 为了操作对象引入的 API .Proxy 可以对目标对象的读取.函数调用等操作进行拦截,然后进行操作处理. 概述 Proxy 与 Reflect 是 ES6 ...

  4. ES6新特性:Javascript中的Reflect对象

    Reflect介绍: Reflect这个对象在我的node(v4.4.3)中还没有实现, babel(6.7.7)也没有实现 ,新版本的chrome是支持的, ff比较早就支持Proxy和Reflec ...

  5. es6学习笔记11--Proxy和Reflect

    Proxy概述 Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程"(meta programming),即对编程语言进行编程. Proxy可以理 ...

  6. ES6:Reflect

    Reflect 概述. Relflect对象与Proxy对象一样,也是ES6为了操作对象而提供的新的API.Reflect对象的设计目的有几个. (1)将Object对象的一些明显属于语言内部的方法( ...

  7. es6 --- Reflect的静态方法

    Reflect.get(target, name, receiver): 查找并返回 target对象的 name属性,若没有,返回undefined var myObject = {foo: 1,b ...

  8. ES6-16 WeakMap与WeakSet、proxy与reflect

    WeakMap/WeakSet 原型上不存在遍历方法(没有部署iterator接口) 成员只能是对象 垃圾回收机制不考虑对成员对象的应用 WeakSet/WeakMap 中的对象都是弱引用,即垃圾回收 ...

  9. 安卓 on a null object reference_详解Object.prototype.__proto__

    Object.prototype 的 __proto__ 属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]] (一个对象或 n ...

  10. “睡服”面试官系列第十七篇之Reflect(建议收藏学习)

    目录 1. 概述 2. 静态方法 2.1Reflect.get(target, name, receiver) 2.2Reflect.set(target, name, value, receiver ...

最新文章

  1. 122112_1452_Word1
  2. 数据通信技术(四:链路聚合)
  3. Nginx/LVS/HAProxy 负载均衡软件的优缺点详解
  4. 底部菜单 点击突起_iOS开发之上下文交互菜单(UIContextMenuInteraction)
  5. 和低压电气有关的71个问题
  6. BLE安全机制从入门到放弃
  7. python辗转相除法求最大公约数的递归函数_Python基于辗转相除法求解最大公约数的方法示例...
  8. I2C总线之(二)---时序
  9. LeetCode 415. 字符串相加(大数加法)
  10. 红帽linux 竞争对手,为什么红帽不把CentOS当作竞争对手?
  11. 【ES】ES 写入数据流程
  12. java jxdatepicker_在Java Swingx中修剪JXDatePicker
  13. LGOJP2831 愤怒的小鸟
  14. Python爬虫--urllib
  15. 安装python第三方模块包时,报错 error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C
  16. 可自定义存储数据总空间的的类int_128函数库
  17. 微信获取公众号二维码
  18. 2017年总结2018年展望
  19. Light-sleep 模式下的电流功耗测试及特性(使用 Wi-Fi)
  20. PR/PO一锅粥,关键信息一图兜

热门文章

  1. Mac删除Python缓存文件
  2. [小技巧1]Word或WPS文献引用、交叉引用方括号编号
  3. CSS 固定定位:固定在版心右侧
  4. Android蓝牙配对
  5. 欧姆龙OMRON PLC之Host Link协议(一)
  6. 2021年1月6日运行Python脚本的一些说明与教程
  7. 巴菲特佛罗里达州立大学演讲
  8. 经典SFM步骤——Lowe2005
  9. 思翼FM30高频头转发模式
  10. AI落地的新范式,就“藏”在下一场软件基础设施的重大升级里