JavaScript-20
1.ES6 Symnol
- 概述
- ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,最大的用法是用来定义对象的唯一属性名
- 基本用法
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Symbol内置属性值</title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Symbol函数栈不能用new命令,因为Symbol是原始数据类型,不是对象 10 //Symbol可以接受一个字符串作为参数,为新创建的Symbol提供描述,以便于区分 11 let st = Symbol("a"); 12 console.log(st);//Symbol(a); 13 //注意:Symbol表示的独一无二的值,使用同样的参数创建的symbol数据不相同 14 let stt = Symbol("a"); 15 console.log(st == stt);//false 16 </script> 17 </body> 18 </html>
- 使用场景
- 作为属性名
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //注意:Symbol作为对象属性名时不能使用.,而是要使用[] 10 //由于.后面的是字符串,所以取到的是字符串sy的属性,而非symbol值sy的属性 11 //由于每个Symbol的值都是不相等的,所以Symbol作为对象的属性名,可以保证属性不重名 12 //写法一: 13 let sy = Symbol("kk"); 14 // let obj = { 15 // [sy]: "key" 16 // } 17 // console.log(obj); 18 //写法二: 19 // let obj = {}; 20 // obj[sy] = "key"; 21 // console.log(obj); 22 //写法三: 23 let obj = { 24 name: 'bh', 25 sex: 'man', 26 age: 30 27 }; 28 //注意这个vlue代表的属性值,不可更改 29 Object.defineProperty(obj,sy,{value: "key"}); 30 console.log(obj); 31 //注意:Symbol作为属性名时,该属性是共有属性,而非私有属性,可以在类的外部进行访问 32 //但不会出现在for…in…、for…of…的循环中,也不会被Object.keys()和Object.getOwnPropertyNames()访问 33 for(key in obj){ 34 console.log(key); 35 }//不包含以Symbol为属性名的属性 36 console.log(Object.keys(obj));//['name', 'sex', 'age'] 37 console.log(Object.getOwnPropertyNames(obj)); 38 //如果需要读取一个对象的Symbol属性 39 //1.Object.getOwnPropertySymbols()只返回Symbol属性名 40 console.log(Object.getOwnPropertySymbols(obj));//[Symbol(kk)] 41 //2.Reflect.ownKeys()返回包含Symbol在内的所有属性名 42 console.log(Reflect.ownKeys(obj));//['name', 'sex', 'age', Symbol(kk)] 43 </script> 44 </body> 45 </html>
-
- 定义常量
- Symbol的值是唯一的,所以不会出现相同值的常量
- 定义常量
1 const COLOR_RED = Symbol("red"); 2 const COLOR_YELLOW = Symbol("yellow"); 3 const COLOR_BLUE = Symbol("blue"); 4 5 function ColorException(message) { 6 this.message = message; 7 this.name = "ColorException"; 8 } 9 function getConstantName(color) { 10 switch (color) { 11 case COLOR_RED : 12 return "COLOR_RED"; 13 case COLOR_YELLOW : 14 return "COLOR_YELLOW "; 15 case COLOR_BLUE: 16 return "COLOR_BLUE"; 17 default: 18 throw new ColorException("Can't find this color"); 19 } 20 } 21 22 try { 23 24 var color = "green"; // green 引发异常 25 var colorName = getConstantName(color); 26 } catch (e) { 27 var colorName = "unknown"; 28 console.log(e.message, e.name); // 传递异常对象到错误处理 29 }
-
- Symbol方法
- Symbol.for()
- Symbol.keyFor()
- Symbol方法
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //1.Symbol.for() 10 //Symbol.for()类似单例模式,首先在全局搜索被登记的Symbol常量中是否含有该字符串参数作为名称的字符串 11 //如果有就立即返回Symbol值,如果没有就创建并返回一个以该字符串参数为名称的Symbol值,并登记在全局变量中 12 let sy = Symbol("yellow");//不会被登记在全局供搜索 13 let sy1 = Symbol.for("yellow"); 14 console.log(sy === sy1);//false 15 let sy2 = Symbol.for("yellow"); 16 console.log(sy1 === sy2);//true 17 //2.Symbol.keyFor() 18 //Symbol.keyFor()返回一个已登记的Symbol类型的值的key,用来检测该字符串参数作为名称的Symbol是否被登记 19 console.log(Symbol.keyFor(sy1));//yellow代表被登记 20 console.log(Symbol.keyFor(sy));//undefined代表未被登记 21 </script> 22 </body> 23 </html>
2.Map对象
- Map对象保存键值对,任何值(对象或者原始值)都可以作为一个键或一个值
- Map和Object的区别
- 一个Object的键只能时字符串或者是Symbol,而一个Map的键可以是任意值
- Map中的键值是有序的(FIFO)原则,而添加到对象中的键不是
- Map的键值对个数可以从size属性中获取,而Object的键值对只能手动计算
- Object都有自己的原型,原型链上的键名可能会和自己在对象上设置的键名产生冲突
- Map中的key
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Map中的key 10 //1.key是字符串 11 var myMap = new Map(); 12 var keyString = "key1"; 13 myMap.set(keyString,"bh1"); 14 var res1 = myMap.get(keyString); 15 var res2 = myMap.get("key1"); 16 // console.log(res1);//bh1 17 // console.log(res2);//bh1 18 // console.log(res1 === res2);//true 19 //2.key是对象 20 var keyObj = {}; 21 myMap.set(keyObj,"bh2"); 22 var res3 = myMap.get(keyObj); 23 var res4 = myMap.get({}); 24 // console.log(res3);//bh2 25 // console.log(res4);//undefined 26 // //keyObj !== {} 27 // console.log(res3===res4);//false 28 //3.key是函数 29 var keyFun = function(){}; 30 myMap.set(keyFun,"bh3"); 31 var res5 = myMap.get(keyFun); 32 var res6 = myMap.get(function(){}); 33 // console.log(res5);//bh3 34 // console.log(res6);//undefined 35 // //keyun !== function(){} 36 // console.log(res5===res6);//false 37 //4.key是NaN 38 myMap.set(NaN,"bh4"); 39 var res7 = myMap.get(NaN); 40 var other = Number("bh4");//NaN 41 var res8 = myMap.get(other); 42 console.log(res7);//bh4 43 console.log(res8);//bh4 44 //注意:虽然NaN与任何值都不相等,但它作为Map键是没有区别的 45 console.log(res7===res8);//true 46 </script> 47 </body> 48 </html>
- Map的迭代
- for…of…
1 、<!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Map迭代 10 //for…of… 11 var myMap = new Map(); 12 myMap.set(0,"zero"); 13 myMap.set(1,"one"); 14 myMap.set(2,"two"); 15 //方法一 16 for(var [key,value] of myMap){ 17 //循环遍历输出key和value的值 18 console.log(key +":"+ value); 19 } 20 //方法二 21 //这个entries方法反悔了一个新的Iterator对象,他按照插入顺序包含了每个元素的[key,value]数组 22 for(var [key,value] of myMap.entries()){ 23 24 console.log(key +":"+ value); 25 } 26 //方法三 27 //keys()方法反悔了一个新的迭代对象,它按照插入顺序包含了每个Map对象的键 28 for(var key of myMap.keys()){ 29 console.log(key); 30 } 31 //方法四 32 //values()返回返回一个新的迭代对象,他按照插入顺序包含了Map对象中每个元素的值 33 for(var value of myMap.values()){ 34 console.log(value); 35 } 36 </script> 37 </body> 38 </html>
-
- forEach()
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 var myMap = new Map(); 10 myMap.set(0,"zero"); 11 myMap.set(1,"one"); 12 myMap.set(2,"two"); 13 myMap.forEach(function(value,key){ 14 console.log(key+": "+value); 15 },myMap);//后面的myMap可加可不加 16 </script> 17 </body> 18 </html>
- Map对象的操作
- Map和Array的切换
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Map和Array的转化 10 //1.array数组转换为Map对象 11 //注意:array必须是二维数组才能满足键值对的要求 12 // var arr = [1,2,3,4]; 13 // var myMap = new Map(arr); 14 // console.log(myMap);//报错Iterator value 1 is not an entry object 15 var arr = [[1,"one"],[2,"two"],[3,"three"]]; 16 var myMap = new Map(arr); 17 //Map(3) {1 => 'one', 2 => 'two', 3 => 'three'} 18 console.log(myMap); 19 //2.Map对象转换为Array数组 20 var map = new Map(); 21 map.set(5,"five"); 22 map.set(6,"fix"); 23 //返回一个二维数组 24 var res = Array.from(map); 25 console.log(res); 26 </script> 27 </body> 28 </html>
-
- Map的克隆
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 var oldMap = new Map([[1,"one"],[2,"two"]]); 10 var newMap = new Map(oldMap); 11 console.log(oldMap); 12 console.log(newMap); 13 //Map对象构造函数生成的实例,迭代出新的对象 14 console.log(oldMap === newMap);//false 15 </script> 16 </body> 17 </html>
-
- Map的合并
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //使用剩余参数可以实现Map的合并 10 var mapOne = new Map([[1,"one"],[2,"two"]]); 11 var mapTwo = new Map([[2,"zore"],[3,"three"],[4,"four"]]); 12 var mapThree = new Map([...mapOne,...mapTwo]); 13 //合并两个Map对象时如果有相同的键,则后面的会覆盖前面的 14 //Map(4) {1 => 'one', 2 => 'zore', 3 => 'three', 4 => 'four'} 15 console.log(mapThree); 16 </script> 17 </body> 18 </html>
3.Reflect和Proxy
- Proxy可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作。
- Reflect可以用于获取对象的行为,它与Object类似。
- Proxy基本用法
- 一个Prixy对象由两个部分组成:target:目标对象、handler:一个对象,声明了代理target的指定行为。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 let target = { 10 name: 'BH', 11 age:30 12 }; 13 let handler = { 14 get:(target,key)=>{ 15 console.log('getting'+key); 16 return target[key]; 17 }, 18 set: (target,key,value)=>{ 19 console.log('setting'+key); 20 target[key] = value; 21 } 22 } 23 let proxy = new Proxy(target,handler); 24 //实际上调用的是handler.get 25 console.log(proxy.name); 26 proxy.sex = '男'; 27 //target可以是空对象 28 //通过构造函数新建实例时其实是对目标对象进行了浅拷贝,所以目标对象和代理对象会相互影响 29 console.log(target); 30 //handler对象也可以为空,相当于不设置拦截操作,直接访问目标对象 31 </script> 32 </body> 33 </html>
-
- 实例方法
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Proxy实例方法 10 //1.get(target,propKey,receiver)用于target对象上的propKey读取操作 11 let target = { 12 name: 'BH', 13 age: 30 14 }; 15 let proxy = new Proxy(target,{ 16 get: (target,propKey,receiver)=>{ 17 return target[propKey]; 18 } 19 }) 20 console.log(proxy.name);//BH 21 //注意get()方法可以继承 22 let newProxy = Object.create(proxy); 23 console.log(newProxy.name);//BH 24 //2.set(target,propKey,value,receiver)用于拦截target对象上的propKey的赋值操作 25 //如果目标对象自身的某个属性,不可写且不可配置,那么set方法将不起作用 26 //注意:在严格模式下set代理没有返回true就会报错 27 var validator = { 28 set:(target,propKey,value,receiver)=>{ 29 if(propKey==='age'){ 30 if(!Number.isInteger(value)){ 31 console.log("The age is not an Integer"); 32 }else if(value > 200){ 33 console.log("The age seems invalid"); 34 }else { 35 target[propKey] = value; 36 } 37 }else{ 38 target[propKey] = receiver; 39 } 40 } 41 } 42 proxy = new Proxy(target,validator); 43 proxy.age = 19; 44 proxy.age = "unkown";//The age is not an Integer 45 console.log(target); 46 //第四个参数receiver表示原始操作行为所在的对象,一般是Proxy实例本身 47 proxy.sex = 'man'; 48 console.log(proxy.sex === proxy);//true 49 //3.apply(target,ctx,args)用于拦截函数的调用、call和reply操作 50 //target表示目标对象,ctx表示目标上下文,args表示目标对象的参数数组 51 function sum(a,b){ 52 return a+b; 53 } 54 handler = { 55 apply: function(target,ctx,args){ 56 return Reflect.apply(...arguments); 57 } 58 } 59 proxy = new Proxy(sum,handler); 60 let res = proxy(2,1); 61 console.log(res);//3 62 //4.hasProperty(target,propKey)用于拦截HasProperty操作,即在判断target对象是否存在propKey属性时 63 //会被这个方法拦截。此方法不判断一个属性是对象的自身的属性还是继承的属性 64 //注意:此方法不拦截for…in…循环 65 handler = { 66 has: function(target,propKey){ 67 return propKey in target; 68 } 69 } 70 let exam = { 71 name: '张三', 72 score: 100 73 }; 74 proxy = new Proxy(exam,handler); 75 console.log('num' in proxy);//false 76 console.log('score' in proxy);//true 77 //5.construct(target,args)用于拦截new命令,返回值必须为对象 78 handler = { 79 construct: function(target,args,newTarget){ 80 return Reflect.construct(target,args,newTarget); 81 } 82 } 83 class Exam { 84 constructor(name) { 85 this.name = name; 86 } 87 } 88 let examProxy = new Proxy(Exam,handler); 89 let proxyObj = new examProxy('BH'); 90 console.log(proxyObj);//Exam {name: 'BH'} 91 //6.deleteProperty(target,propKey)用于拦截delete操作 92 //如果这个方法抛出错误就返回false,这个属性就无法被delete命令删除 93 //7.defineProperty(target,propKey,propDesc)用于拦截Object.definePro 94 //若目标对象不可扩展,增加目标对象上不存在的属性就会报错;若属性不可写或者不可配置 95 //则不能改变这些属性 96 handler = { 97 defineProperty: function(target,propKey,propDesc){ 98 //由实践得出返回值的true和false并不能决定目标对象是否能扩展 99 //重要的是是否进行赋值操作 100 if(propKey === 'name'){ 101 target[propKey] = propDesc.value; 102 return true; 103 }else{ 104 // target[propKey] = propDesc.value; 105 return false; 106 } 107 } 108 } 109 target = {}; 110 proxy = new Proxy(target,handler); 111 proxy.name = "Tom"; 112 console.log(target); 113 proxy.age = 18; 114 console.log(target); 115 //8.erty操作 116 //getOwnPropertyDescriptor(target,propKey) 117 //用于拦截Object.getOwnPropertyD()返回值为属性描述对象或者undefined 118 handler = { 119 getOwnPropertyDescriptor:(target,propKey)=>{ 120 return Object.getOwnPropertyDescriptor(target,propKey); 121 } 122 } 123 target = { 124 name: "Tom" 125 }; 126 proxy = new Proxy(target,handler); 127 console.log(Object.getOwnPropertyDescriptor(proxy,'name')); 128 //9.ptor属性 129 //getPrototypeOf(target)主要用于拦截获取对象原型的操作 130 /* 131 包括 132 -Object.prototype.__proto__ 133 -Object.prototype.isPrototypeOf() 134 -Object.getPrototypeOf() 135 -Reflect.getPrototypeOf() 136 -instanceof 137 */ 138 exam = {}; 139 proxy = new Proxy({},{ 140 getPrototypeOf: function(target){ 141 //注意返回值必须是对象或者null,否则报错 142 //如果目标对象不可扩展,getPrototype方法必须返回目标对象的原型对象 143 // return null;//null 144 return exam;//{} 145 } 146 }) 147 res = Object.getPrototypeOf(proxy); 148 console.log(res);//{} 149 //10.isExtensible(target)用于拦截Object.isExtensible是否可以向对象添加新属性操作 150 //该方法只能返回布尔值,否则返回值会被自动转换为布尔值 151 //注意他的返回值必须与目标对象的isExtensible属性保持一致否则就会抛出错误 152 proxy = new Proxy({},{ 153 isExtensible: function(target){ 154 //抛出错误isExtensible' on proxy: trap result、 155 // return false; 156 return true; 157 } 158 }) 159 console.log(Object.isExtensible(proxy)); 160 //11.ownKeys(target) 161 //该方法拦截自身属性的读取操作 162 /* 163 包括 164 -Object.getOwnPropertyNames() 165 -Object.getOwnPropertySymbols() 166 -Object.keys() 167 -for…in… 168 */ 169 //注意方法返回的数组成员,只能是字符串或者Symbol值,否则会报错 170 //(一)若目标对象中含有不可配置的属性,则必须将这些属性在结果中返回,否则会报错 171 //(二)若目标对象不可扩展,则必须全部返回且只能返回目标对象包含的所有属性 172 // 不能包含不存在的属性,否则也会报错 173 let sy = Symbol("sex"); 174 proxy = new Proxy({ 175 name: 'BH', 176 [sy]: 'man', 177 age: 30 178 },{ 179 ownKeys(target){ 180 //返回结果中三种属性会被过滤 181 // -目标对象没有的属性 182 // -属性名为Symbol值的属性 183 // -不可遍历的属性 184 return ['name','sex',Symbol.for("sex")]; 185 } 186 }); 187 console.log(Object.keys(proxy));//['name'] 188 //12.preventExtensions(target) 189 //该方法必须返回一个布尔值,否则会自动转换为布尔值 190 //只有目标对象不能扩展时才能返回true,否则会报错 191 proxy = new Proxy({},{ 192 preventExtensions: (target)=>{ 193 // return true;//抛出异常 194 Object.preventExtensions(target); 195 return true; 196 } 197 }) 198 console.log(Object.preventExtensions(proxy));//Proxy{} 199 //13.setPrototypeOf:用来拦截Object.setPrototypeOf方法 200 //返回值必须为布尔值,否则会被自动转换为布尔值。 201 //若目标对象不可扩展,setPrototypeOf方法不得改变目标对象的原型 202 let proto = {}; 203 proxy = new Proxy(function(){},{ 204 setPrototypeOf: function(target,proto){ 205 return true; 206 } 207 }) 208 Object.setPrototypeOf(proxy,proto) 209 //14.Proxy.revocable() 210 //用于返回一个可取消的Proxy实例 211 let {proxy,revoke} = Proxy.revocable({},{}); 212 proxy.name = "Tom"; 213 revoke(); 214 console.log(proxy.name);// Cannot perform 'get' on a proxy that has been revoked 215 </script> 216 </body> 217 </html>
- Reflect
- ES6将一些明显属于语言内部的方法移植到了Reflect对象上,Reflect对象使用函数的而方式实现类Object的命令式操作
- 静态方法
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Reflect静态方法 10 //1.Reflect.get(target,name,receiver) 11 //查找并返回target对象的name属性 12 let exam = { 13 name: 'BH', 14 age: 30, 15 get info(){ 16 return this.name+this.age; 17 } 18 } 19 console.log(Reflect.get(exam,'name'));//BH 20 //当target对象中存在name属性的getter方法,getter方法的this会绑定 21 // let receiver = { 22 // name: 'BK', 23 // age: '22' 24 // } 25 // console.log(Reflect.get(exam,'info',receiver));//BK22 26 //当name为target不存在的属性时,返回undefined 27 console.log(Reflect.get(exam,'sex'));//undefined 28 //当target不是对象是,报错 29 // console.log(Reflect.get(1,'name'));//Reflect.get called on non-object 30 //2.Reflect.set(target,name,value,receiver) 31 //将target的name属性设置为value。返回值为布尔值,true代表修改成功,false表示失败 32 //当target为不存在的对象时会报错 33 let lover = { 34 name: 'BH', 35 age: 18, 36 set info(value){ 37 this.age = value; 38 } 39 } 40 console.log(Reflect.set(lover,'age',30));//true 41 console.log(lover);//{name: 'BH', age: 30} 42 //对象没有该属性时会先添加再赋值 43 Reflect.set(lover,'sex','man'); 44 console.log(lover); 45 //value为空时会将属性清除 46 Reflect.set(lover,'sex',); 47 console.log(lover);//undefined 48 //当target对象中存在name属性的set方法时,setter中的this会绑定receiver 49 //所以修改的实际上是receiver属性 50 let receiver = { 51 age: 16 52 }; 53 Reflect.set(lover,'age',1,receiver); 54 console.log(receiver.age); 55 console.log(lover); 56 //3.Reflect.has(obj,name); 57 //是name in obj指令的韩淑华,用于查找name属性是否在obj对象中存在 58 //返回值为布尔值,如果obj不是对象就会报错TypeError 59 let singer = { 60 name: 'bh', 61 age: 18 62 } 63 console.log(Reflect.has(singer,'name'));//true 64 //4.Reflect.deleteProperty(obj,property) 65 //是delete obj[property]的函数化,返回值为bool,如果obj不是对象就会报错TypeError 66 Reflect.deleteProperty(singer,'age'); 67 console.log(singer);//{name: 'bh'} 68 //注意当property不存在时也会返回true 69 //4.Reflect.construct(obj,args) 70 //等同于 new target(...args) 71 function sing(song){ 72 this.song = song; 73 } 74 console.log(Reflect.construct(sing,['Drown']));//sing {song: 'Drown'} 75 //5.Reflect.getPrototypeOf(obj) 76 //用于读取obj的__proto__属性,在obj不是对象时会报错 77 class Exam{}; 78 let obj = new Exam(); 79 console.log(Reflect.getPrototypeOf(obj) === Exam.prototype);//truf 80 //6.Reflect.setPrototypeOf(obj,newProto) 81 //用于设置目标对象的prototype 82 obj = {}; 83 console.log(Reflect.setPrototypeOf(obj,Array.prototype));//true 84 //7.Reflect.apply(func,thisArg,args) 85 //等同于Function.prototype.apply.call(func,thisArg,args) 86 //func表示目标函数 87 //thisArg表示目标函数绑定的this对象 88 //args表示目标函数调用时传入的参数列表 89 //若目标函数无法调用报错TypeError 90 console.log(Reflect.apply(Math.max,Math,[1,2,56,8]));//56 91 //8.Reflect.defineProperty(target,propertyKey,attributes) 92 //用于为目标对象定义属性,如果target不是对象会抛出错误 93 let myDate = {}; 94 Reflect.defineProperty(myDate,'now',{ 95 value:()=>Date.now() 96 }); 97 console.log(myDate.now());//1650705739403 98 //9.Reflect.getOwnPropertyDescriptor(target,propertyKey) 99 //用于得到target对象的propertyKey属性的描述对象 100 //在target不是对象时,会抛出错误表述参数非法 101 exam = {}; 102 Reflect.defineProperty(exam,'name',{ 103 value: true, 104 enumerable: false 105 }) 106 let res = Reflect.getOwnPropertyDescriptor(exam,'name'); 107 console.log(res);//{value: true, writable: false, enumerable: false, configurable: false} 108 //当该属性在target中不存在时返回undefined 109 //10.Reflect.isExtensible(target) 110 //测试目标对象是否可扩展,如果target不是对象会抛出错误 111 //11.Reflect.preventExtensions(target) 112 //用于让target对象改变为不可扩展,如果target不是对象会抛出错误 113 //12.Reflect.ownKeys 114 //用于返回target对象的所有属性 115 //等同于Object.getOwnPropertyNames和Object.getOwnPropertySymbols之和 116 </script> 117 </body> 118 </html>
- 组合使用
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //Reflect对象的方法与Proxy对象的方法是一一对应的 10 //Proxy对象诶通过调用Reflect的默认方法获取默认行为,然后进行额外操作 11 let exam = { 12 name: 'Tom', 13 age: 18 14 } 15 let handler = { 16 get:(target,key)=>{ 17 console.log('getting'+key); 18 return Reflect.get(target,key); 19 } 20 } 21 let proxy = new Proxy(exam,handler); 22 console.log(proxy.name); 23 //gettingname 24 //Tom 25 </script> 26 </body> 27 </html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本