es6相关知识

ES6入门教程–阮一峰

1. 变量声明-- let

let a = 1;

注意:

  1. 不能重复声明
  2. 存在块级作用域
  3. 作用域链仍然存在
  4. 存在暂时性死区,即不能在声明前就使用变量(没有变量提升)
  5. var 在全局作用域下声明变量会导致变量挂载在 window对象 上,let和const声明的变量不会
//例
var a = 1
let b = 1
const c = 1
console.log(window.a) // 1
console.log(window.b) // undefined
console.log(window.c) // undefined

2. 常量声明-- const

const PI = 3.14;

  1. 不能重复声明
  2. 存在块级作用域
  3. 作用域链仍然存在
  4. 存在暂时性死区,即不能在声明前就使用变量(没有变量提升)
  5. var 在全局作用域下声明变量会导致变量挂载在 window对象 上,let和const声明的变量不会
  6. 必须要赋初始值
  7. 一般常量名用大写
  8. 常量值不能修改
  9. 数组和对象的内容可以修改(其指向的地址不变,只是修改了内容),所以最好使用const声明数组和对象
    例:const Arr = [“aaa”,“bbb”,“ccc”];
    Arr.push(“ddd”);

3. 解构赋值

es6允许按照一定模式从可迭代对象(字符串、数组、对象)中提取值,对变量进行赋值,这被称为解构赋值。

  1. 字符串的解构赋值

    let str= '1234';
    let [a,b,c] = str;
    console.log(a);//1
    
  2. 数组的解构赋值

    const arr = ["小迟","小娜","天仙"];
    let [chi,na,xian] = arr;
    console.log(chi);//小迟
    
  3. 对象的解构赋值

    const chi = {
    	name:"迟娜",
    	age:18,
    	hobby:function(){
    		console.log("看书");
    	}
    }
    
    let {name,age,hobby} = chi;
    console.log(hobby);//function(){console.log("看书");}
    hobby();//看书
    

4. 展开运算符 […]

… 展开运算符能将数组、对象等转化为逗号分隔的参数序列

//数组
<script>
	const numbers = ['1','2','3'];
	const tfboys = ["易烊千玺",...numbers,"王源","王俊凯"];
	console.log(tfboys);
	//(6)["易烊千玺", "1", "2", "3", "王源", "王俊凯"]
</script>

<script>
//对象
const obj1 = {
	a:1,
	b:2
};
const obj2 = {
	...obj1,
	c:3,
	d:4
};
console.log(obj2);
//{a: 1, b: 2, c: 3, d: 4}
</script>

5. 模板字符串

模版字符串是增强版字符串,用反引号标识,可以当做普通字符串使用,也可以用来定义多行字符串或者在字符串中嵌入变量

  1. 模板字符串中可以直接出现换行符,“”或‘’不能
let str = `<ul>
			<li>小迟迟</li>
			<li>小娜娜</li>
			<li>迟小娜</li>
			</ul>`
document.write(str);
  1. 可以使用${}进行变量拼接
let name = '小娜';
let des = `${name}是个小仙女`;
console.log(des);//小娜是个小仙女
  1. String.raw()

6.set

ES6 提供了一种新的类似于数组的数据结构set(集合),但成员的值都是唯一的,
集合实现了iterator接口,所以可以使用「扩展运算符 …』和「for…of…』进行遍历,

ES6规定,所有部署了Iterator接口的对象(可遍历对象)都可以通过for…of去遍历,而for…in仅仅可以遍历对象。这也就意味着,数组也可以用for…of遍历,这极大地方便了数组的取值,且避免了很多程序用for…in去遍历数组的恶习。扩展运算符本质上也就是for…of循环的一种实现。

集合的属性和方法:
1)size返回集合的元素个数
2)add()增加一个新元素,返回添加新元素的set集合,可以用于链式调用
3)delete()删除元素,返回boolean值
4)has()检测集合中是否包含某个元素,返回boolean值
5)clear()清除数组

<script>
	//声明一个空set
	let s = new Set();
	console.log(s);//Set(0) {}
	//声明一个非空set
	let ss = new Set(["aa","bb","cc"]);
	console.log(ss);//Set(3) {"aa", "bb", "cc"}
	//元素的个数
	console.log(ss.size);//3
	//添加一个元素
	ss.add("dd");
	//删除一个元素
	ss.delete("bb");
	console.log(ss);//Set(3) {"aa", "cc", "dd"}
	//检测是否含有,有返回true,无返回false
	console.log(ss.has("bb"));//false
	//遍历结合
	/*
	 * 结果:
	 * aa
	 * cc
	 * dd
	 */
	for(let v of ss){
		console.log(v);
	}
	console.log(...ss);//aa cc dd
	//清空集合
	ss.clear();
	console.log(ss);//Set(0) {}
</script>
  • 集合的应用
<script>
	const arr1 = [1,2,3,3,3,6,6,8,9,9];
	const arr2 = [6,6,7,8,9,9];
	
	//1.数组去重
	const result = [...new Set(arr1)];
	console.log(result);//(6) [1, 2, 3, 6, 8, 9]
	
	//2.数组求交集
	const result1 = [...new Set(arr1)].filter(item=>{
		let s2 = new Set(arr2);
		if(s2.has(item)){
			return true;
		}else{
			return false;
		}
	});
	console.log(result1);//(3) [6, 8, 9]
	
	//3.数组求并集
	const arr3 = [...arr1,...arr2];
	const result2 = [...new Set(arr3)];
	console.log(result2);(7) [1, 2, 3, 6, 8, 9, 7]

	//4.数组求差集 arr1-arr2(在arr1不在arr2中的元素)
	const result3 = [...new Set(arr1)].filter(item=>{
		let s2 = new Set(arr2);
		if(s2.has(item)){
			return false;
		}else{
			return true;
		}
	});
	console.log(result3);//(3) [1, 2, 3]
</script>
  • Set 结构的实例有四个遍历方法,可以用于遍历成员。

    Set.prototype.keys():返回键名的遍历器
    Set.prototype.values():返回键值的遍历器
    Set.prototype.entries():返回键值对的遍历器
    Set.prototype.forEach():使用回调函数遍历每个成员

    Set的遍历顺序就是插入顺序。

  1. keys(),values(),entries()
    keys(),values(),entries()方法返回的都是遍历器对象。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

    let set = new Set(['red', 'green', 'blue']);
    for (let item of set.keys()) {
      console.log(item);
    }
    // red
    // green
    // blue
    
    for (let item of set.values()) {
      console.log(item);
    }
    // red
    // green
    // blue
    
    for (let item of set.entries()) {
      console.log(item);
    }
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]
    //entries方法返回的遍历器,同时包括键名和键值
    //所以每次输出一个数组,它的两个成员完全相等。
    
  2. forEach()
    Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。

    let set = new Set([1, 4, 9]);
    set.forEach((value, key) => {
    	console.log(key + ' : ' + value)
    })
    // 1 : 1
    // 4 : 4
    // 9 : 9
    

7.map

ES6提供了一种类似于Object的新的数据结构–Map(字典)。可以理解为是Object的超集,用来存放键值对的集合,但是“键” 的范围不限于字符串,可以是各种类型的值(包括对象),可以用来存储不重复的值。Map实现 了iterator接口,所以可以使用『扩展运算符』和「 for…of…」进行遍历。Map 的属性和方法:
1)size返回Map 的元素个数
2)set(key,value) 增加一个新元素,返回增加新元素的Map集合,可用于链式调用
3)get(key) 返回键名对象的键值
4)has(key) 检测Map中是否包含某个元素,返回boolean值
5)delete(key)删除某个键
6)clear() 清空集合

<script>
	//声明一个空map
	let m = new Map();
	console.log(m);//Map(0) {}
	//键与值都是字符串
	m.set("name","chi");
	//键、值都为对象
	let key = {
		name:"aa"
	}
	m.set(key,function(){
		console.log("aa");
	})
	console.log(m);//Map(2) {"name" => "chi", {…} => ƒ}
	//map的大小
	console.log(m.size);//2
	//获取
	console.log(m.get("name"));//chi
	console.log(m.get(key));//ƒ (){console.log("aa");}
	//检测是否包含
	console.log(m.has(key));//true
	//遍历
	/*
	 * 遍历结果(数组)
	 * (2) ["name", "chi"]
	 * (2) [{…}, ƒ]
	 */
	for(let v of m){
		console.log(v);
	}
	console.log(...m);//(2) ["name", "chi"] (2) [{…}, ƒ]
	//删除键为xx的map
	m.delete(key);
	console.log(m);//Map(1) {"name" => "chi"}
	//清空
	m.clear();
	console.log(m);//Map(0) {}
</script>
  • Map 结构原生提供三个遍历器生成函数和一个遍历方法。

    Map.prototype.keys():返回键名的遍历器。
    Map.prototype.values():返回键值的遍历器。
    Map.prototype.entries():返回所有成员的遍历器。
    Map.prototype.forEach():遍历 Map的所有成员。

    Map 的遍历顺序就是插入顺序。

    const map = new Map([
      ['F', 'no'],
      ['T',  'yes'],
    ]);
    
    for (let key of map.keys()) {
      console.log(key);
    }
    // "F"
    // "T"
    
    for (let value of map.values()) {
      console.log(value);
    }
    // "no"
    // "yes"
    
    for (let item of map.entries()) {
      console.log(item[0], item[1]);
    }
    // "F" "no"
    // "T" "yes"
    
    // 或者
    for (let [key, value] of map.entries()) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    
    // 等同于使用map.entries()
    for (let [key, value] of map) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    
    //例2:
    var myMap = new Map();
    myMap.set('0', 'foo');
    myMap.set(1, 'bar');
    myMap.set({}, 'baz');
    
    var mapIter = myMap.keys();
    
    console.log(mapIter.next().value); // "0"
    console.log(mapIter.next().value); // 1
    console.log(mapIter.next().value); // Object
    
  • set和map参考

  • Object.keys()、Object.values()、Object.entries()的用法

8. 函数参数

1). 参数设置默认值

es6允许给函数参数设置默认值

<script>
	function add1(a,b,c){//c的值为undefined
		return a+b+c;
	}
	let result1 = add1(1,2);
	console.log(result1);//NaN
	//1. 设置形参初始值,具有默认值的参数一般位置比较靠后
	function add2(a,b,c=3){
		return a+b+c;
	}
	let result2 = add2(1,2);
	console.log(result2);//6
</script>
  • 函数传参与解构赋值结合
/*
<script>
	function connect({host,username,password,port}){
		console.log(host);
		console.log(username);
		console.log(password);
		console.log(port);
	}
	connect({
		host:"127.0.0.1",
		username:"root",
		password:"root",
		port:3306
	})
</script>
*/

<script>
	function connect({host='127.0.0.1',username,password,port=3306}){
		console.log(host);
		console.log(username);
		console.log(password);
		console.log(port);
	}
	connect({
		username:"root",
		password:"root"
	})
</script>
2). rest参数

es6 引入rest参数,代替arguments,用于获取函数的参数

<script>
	//es5
	function test1(){
		console.log(arguments);
	}
	//类数组对象Arguments(3) ["张颜齐", "姚琛", "任豪", callee: ƒ, Symbol(Symbol.iterator): ƒ]
	test1("张颜齐","姚琛","任豪");
	
	
	//es6的rest参数,rest参数必须要放在参数的最后
	function test2(a,b,...args){
		console.log(a);
		console.log(b);
		console.log(args);
	}
	//娜娜
	//小迟
	//数组(3) ["张颜齐", "姚琛", "任豪"]
	test2("娜娜","小迟","张颜齐","姚琛","任豪");
</script>

9. 箭头函数

es6允许使用箭头函数(=>)定义函数。
//声明一个函数
声明函数

注意:

  1. 允许给函数参数设置初始值
  2. 箭头函数本身不创建this,也可以说箭头函数本身没有this,但是在它声明时可以捕获其声明环境(全局和函数两种环境)的this供自己使用。this一旦被捕获,以后将不再变化。(箭头函数的this是静态的,this始终指向函数声明所在的作用域的this的值),可以用来解决闭包中使用普通函数导致的this指向不明确的问题
<script>
	function person() {
	  console.log(this);
	  (() => {
	    console.log(this);
	  })();
	}
	person();
	/*
	 * 执行结果:
	 * window
	 * window
	 */
	let P = {name:"迟"};
	person.call(P);
	/*
	 * 执行结果:
	 * {name: "迟"}
	 * {name: "迟"}
	 */



const shape = {
  radius: 10,
  diameter() {
    return this.radius * 2;
  },
  perimeter: () => 2 * Math.PI * this.radius  // 该箭头函数的声明环境是全局环境,所以this指向window
};

shape.diameter(); // 20
shape.perimeter(); // NaN
</script>

  1. 箭头函数没有构造函数 constructor,所以也不能使⽤ new 来调
    ⽤,即箭头函数不能作为构造函数来实例化对象,会报错。
  2. 箭头函数没有原型对象。
  3. 箭头函数不能使用arguments变量(es5中函数内部有一个arguments变量来保存实参),使用rest参数
  4. 箭头函数的简写:1)当形参有且只有一个的时候可以省略小括号。2)当代码体只有一条语句的时候可以省略大括号,return 关键字也必须省略,函数的执行结果就是函数返回值。
let pow = n =>n*n;
console.log(pow(9));//81

10.数组方法扩展

(1).Array.from()方法

把一个类数组转换成真正的数组,该方法的返回值是一个数组。

<script>
	function test1(){
		console.log(arguments);
	}
	//类数组:有下标有length
	test1(1,2,3);//类数组Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
	function test2(){
		let arr = Array.from(arguments)
		console.log(arr);
	}
	test2(1,2,3);//数组(3) [1, 2, 3]
</script>
(2).Array.of()方法

将所有参数组成一个数组并返回

<script>
	let arr = Array.of(1,'2',[1,3]);
	console.log(arr);//(3) [1, "2", Array(2)]
</script>
(3).find()方法

查找数组中满足要求的第一个元素,没有则返回undefind【参数是一个回调函数】

<script>
	let arr = [1,2,5,6];
	let val = arr.find((item)=>{
		return item >= 5;
	});
	console.log(val);//5
</script>
(4).findIndex()方法

查找数组中满足要求的第一个元素的下标索引,没有则返回-1【参数是一个回调函数】

<script>
	let arr = [1,2,5,6];
	let index = arr.findIndex((item)=>{
	    return item >= 5;
	});
	console.log(index);//2
</script>

11. 对象的简单书写

es6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。

let name = '迟娜';
const people = {
	name,
	hobby(){
		console.log("看书");
	}
}

console.log(people);

12.对象扩展

  1. Object.is(value1,value2)判断两个值是否完全相等。

    console.log(NaN === NaN);//false
    console.log(Object.is(NaN,NaN));//true
    
  2. Object.assign(obj1,obj2) 对象合并,obj2中的属性值会将obj1中同名的属性值覆盖掉

    const obj1 = {
    	name:"小迟",
    	age:18,
    	sex:"女",
    	like:"玩手机"
    }
    const obj2 = {
    	name:"小迟",
    	age:18,
    	sex:"男",
    	hobby:"看书"
    }
    console.log(Object.assign(obj1,obj2));
    //{name: "小迟", age: 18, sex: "男", like: "玩手机", hobby: "看书"}
    
  3. Object.setPrototypeOf(obj1,obj2)设置obj2是obj1的原型对象
    Object.getPrototypeOf(obj)获取obj的原型对象

    const school = {
    	name:"山东大学"
    }
    
    const cities = {
    	xiaoqu : ["济南","威海","青岛"]
    }
    Object.setPrototypeOf(school,cities);
    console.log(Object.getPrototypeOf(school));//{xiaoqu: Array(3)}
    console.log(school);//{name: "山东大学"}
    
    
  4. Object.freeze()方法

    // *引用类型的内部属性值无法被常量化
      const obj = {
        teacher: 'aa',
        age: 18
      }
      obj.teacher = 'bb';
      console.log(obj.teacher) //'bb'
      
      // * 引用类型如何冻结
      // Object.freeze();
      Object.freeze(obj);
      obj.teacher = 'cc'; // 不会改变值,并且不会报错
      console.log(obj.teacher) //'bb'
    
      const obj2 = {
        teacher: '云隐',
        leader: '黄小杨',
        zhuawa: ['部部', '小可']
      };
      Object.freeze(obj2); // freeze无法冻结嵌套引用类型
    
      // 思路: 嵌套遍历并且逐层freeze
      function deepFreeze(obj = {}) {
        Object.freeze(obj);
        // 兼容对象和数组
        (Object.key(obj) || []).forEach(key => {
          if(type obj[key] === 'object') {
            deepFreeze(obj[key]);
          }
        })
      }
    

13.class

14. Symbol

Symbol是es6引进的一种新的基本数据类型(六种基本数据类型:Number、String、Null、Boolean、Undefined、Symbol),表示独一无二的值,唯一性对用户来说是不可见的。注: 遇到唯一性的场景时要想到 Symbol

注意:

  1. Symbol的值是唯一的,可以用作属性名(作为对象属性名时,不能用点运算符,可以用 [ ] ),用来解决命名冲突的问题,并且可以有效的避免对象属性被修改。比如,在某个class类中定义一个内部方法,可以使用Symbol用作方法名,避免子类对该方法进行重写。
const myMethod = Symbol('myMethod')
class myClass {
	constructor(context) {
 	// 初始化
 }

 // myMethod
 [myMethod](options) {}

 doSomeThing(event) {
   if (event) {
     this[myMethod]()
   }
 }
}

export default myClass
  1. Symbol值不能与去他数据进行运算和比较
  2. Symbol定义的对象属性不能使用for…in 循环遍历,但是可以使用Reflect:ownKeys来获取对象的所有键名。
<script>
	//1创建Symbol
	let s = Symbol();
	
	//2创建Symbol,传入描述字符串,
	//传入相同的值,创建的也不是同一个Symbol
	let s2 = Symbol("这是Symbol");
	let s3 = Symbol("这是Symbol");
	console.log(s2 === s3);//false
	console.log(Symbol.keyFor(s2))//undefined
	
	//3创建Symbol,传入描述字符串,
	//传入相同值,创建的是同一个Symbol
	let s4 = Symbol.for("这是Symbol");
	let s5 = Symbol.for("这是Symbol");
	console.log(s4 === s5);//true
	console.log(Symbol.keyFor(s4))//这是Symbol
</script>
  • 重点:Symbol.iterator-- 迭代器

    <script>
    	/*let obj = {
    		a:1,
    		b:2,
    		c:3
    	}
    	//报错:obj对象没有Symbol.iterator属性,不能遍历
    	for(let val of obj){
    	    console.log(val);
    	}
    	*/
    	/*
    	迭代器基础语法
    	obj[Symbol.iterator]=function(){
    		return {
    			next(){
    				return {
    					//循环过程输出的值
    					value:'1',
    					//false表示没有完成,true表示完成
    					done:false
    				}
    			}
    		}
    	}
    	*/
    	//*******添加迭代器***********
    	let obj = {
    	    a: 1,
    	    b: 2,
    	    c: 3
    	};
    	obj[Symbol.iterator] = function(){
    	    // 迭代协议
    	    let values = Object.values(obj);//(3) [1, 2, 3]
    	    let index = 0;
    	    return {
    	        next(){
    	            if(index >= values.length){
    	                return {
    	                    done: true
    	                }
    	            } else {
    	                return {
    	                    done: false,
    	                    value:values[index++]
    	                }
    	            }
    	        }
    	    }
    	};
    	for(let val of obj){
    	    console.log(val);
    	}
    	//结果:
    	//1
    	//2
    	//3
    </script>
    

15.生成器(Generator)

生成器(Generator)是JavaScript ES6引入的特性,用来解决异步编程的一种方式。Generator 最大的特点就是可以控制函数的执行,它让我们可以分段执行一个函数。生成器(Generator)就是一个自带遍历器(Iterator)的函数。执行Generator函数会返回一个遍历器对象,每一次Generator函数里面的yield都相当一次遍历器对象的next()方法,并且可以通过next(value)方法传入自定义的value,来改变Generator函数的行为

function* printOneToThree() {
//yield  放弃
//实质上将该函数以yield为界分解成若干小函数,每走一个next就执行一个小函数
  yield 1;
  yield 2;
  yield 3;
}

let iterator= printOneToThree();
//我们每调用一次iterator.next()语句,就会运行一个yield表达式,直到所有的yield表达示全部运行完毕。做到分段执行一个函数
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

yield

yield既可以传参,也可以返回

<script>
	function * gen(arg) {
	  console.log(arg);//AAA
	  let one = yield 1;
	  console.log(one);
	  let two = yield 2;
	  console.log(two);
	  let three = yield 3;
	  console.log(three);
	}
	
	let iterator= gen('AAA');
	//我们每调用一次iterator.next()语句,就会运行一个yield表达式,
	//直到所有的yield表达示全部运行完毕。做到分段执行一个函数
	console.log(iterator.next()); // {value: 1, done: false}
	//next方法可以传入实参,第二条next的实参作为第一条yield的返回值
	console.log(iterator.next('BBB')); // {value: 2, done: false}
	console.log(iterator.next()); // {value: 3, done: false}
	console.log(iterator.next('CCC')); // {value: undefined, done: true}

</script>

结构图

生成器应用

1). 异步编程–定时器操作

<script>	
	//一秒钟输出111,
	//之后两秒钟输出222,
	//之后三秒钟三秒钟输出333
	/*
	setTimeout(function(){
		console.log('111');
		setTimeout(function(){
			console.log('222');
			setTimeout(function(){
				console.log('333');
			},3000);
		},2000);
	},1000);
	*/
	//改写上述回调地狱
	function time1(){
		setTimeout(function(){
			console.log('111');
			it.next();
		},1000);
	}
	function time2(){
		setTimeout(function(){
			console.log('222');
			it.next();
		},2000);
	}
	function time3(){
		setTimeout(function(){
			console.log('333');
			it.next();
		},3000);
	}
	
	function * gen(){
		yield  time1();
		yield  time2();
		yield  time3();
	}
	
	let it = gen();
	it.next();
</script>

16.promise

17. Proxy

在 Vue3.0 中将会通过 Proxy 来替换原本的 Object.defineProperty 来实现数据响应式。
Proxy 是 ES6 中新增的功能。Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问或者操作,都必须先通过这层拦截。这样可以针对Proxy实例进行操作,而不是直接针对目标对象target进行操作。

//target 代表需要添加代理的对象
//handler 用来自定义对象中的操作,比如可以用来自定义 set 或者 get 函数。
let p = new Proxy(target, handler)
  • 注意,要使得Proxy起作用,必须针对Proxy实例进行操作,而不是针对目标对象target进行操作。
    如果handler没有设置任何拦截,那就等同于直接通向原对象。

    //例:
    var proxy = new Proxy({}, {
     get: function(target, propKey) {
        console.log(propKey);
      }
    });
    
    proxy.time //time
    proxy.name //name
    

    Proxy拦截操作

18. Reflect

Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的有这样几个。

  1. 将原生的一些零散分布在Object、Function或者全局函数里的方法(如apply、delete、get、set等等),统一整合到Reflect上,这样可以更加方便更加统一的管理一些原生API。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。

  2. 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

    // 老写法
    try {
      Object.defineProperty(target, property, attributes);
      // success
    } catch (e) {
      // failure
    }
    
    // 新写法
    if (Reflect.defineProperty(target, property, attributes)) {
      // success
    } else {
      // failure
    }
    
  3. 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

  4. Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础,进行扩展。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

    var loggedObj = new Proxy(obj, {
      get(target, name) {
        console.log('get', target, name);
        return Reflect.get(target, name);
      },
      deleteProperty(target, name) {
        console.log('delete' + name);
        return Reflect.deleteProperty(target, name);
      },
      has(target, name) {
        console.log('has' + name);
        return Reflect.has(target, name);
      }
    });
    
Reflect静态方法

Reflect对象一共有 13 个静态方法。这些方法的作用,大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。

Reflect.apply(target, thisArg, args)
Reflect.construct(target, args)
Reflect.get(target, name, receiver)
Reflect.set(target, name, value,receiver)
Reflect.defineProperty(target, name, desc)
Reflect.deleteProperty(target, name)
Reflect.has(target, name)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target,prototype)

19. babel

babel是一个 ES6 转码器,可以将 ES6 代码转为 ES5 代码,以便兼容那些还没支持ES6的平台。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值