สะท้อนการแนะนำ:
วัตถุสะท้อนยังไม่ได้ถูกนำไปใช้ในโหนดของฉัน (v4.4.3) และ Babel (6.7.7) ไม่ได้ใช้งาน รองรับ Chrome เวอร์ชันใหม่ FF สนับสนุนพร็อกซีและไตร่ตรองมาเป็นเวลานาน หากคุณต้องการให้โหนดสนับสนุนการสะท้อนคุณสามารถติดตั้ง Harmony-Reflect;
การไตร่ตรองไม่ใช่ตัวสร้าง เมื่อใช้แล้วจะถูกเรียกโดยตรงผ่าน Reflect.method () วิธีการสะท้อนบางอย่างคล้ายกับพร็อกซีและวิธีการสะท้อนกลับส่วนใหญ่มีการใช้วิธีการดั้งเดิม
สิ่งที่ต้องใช้สะท้อน
ต่อไปนี้เป็นเหตุผลบางประการที่มีการใช้การไตร่ตรอง ที่อยู่การแปล: ไตร่ตรองแปลคร่าวๆ:
1: ค่าผลตอบแทนที่มีประโยชน์มากขึ้น: Reflect มีวิธีการบางอย่างเช่นวิธีการวัตถุใน ES5 เช่น: Reflect.GetOwnPropertyDescriptor และ Reflect.defineProperty อย่างไรก็ตามหาก Object.defineProperty (OBJ, NAME, DESC) ดำเนินการสำเร็จมันจะส่งคืน OBJ และข้อผิดพลาดอื่น ๆ ที่เกิดจากเหตุผลอื่น Reflect.defineProperty จะส่งคืนเท็จหรือจริงเท่านั้นเพื่อระบุว่ามีการตั้งค่าคุณสมบัติของวัตถุหรือไม่ รหัสต่อไปนี้สามารถ refactored:
ลอง {object.defineproperty (obj, ชื่อ, desc); // คุณสมบัติที่กำหนดสำเร็จ} catch (e) {// ความล้มเหลวที่เป็นไปได้ (และอาจจับข้อยกเว้นที่ไม่ถูกต้อง)}สร้างใหม่เช่นนี้:
if (rechorm.defineProperty (obj, name, desc)) {// ความสำเร็จ} else {// failure}วิธีการอื่น ๆ เช่น delect.set, rechers.deleteProperty, rechers.preventextensions, retref.setPrototypeof, ทั้งหมดสามารถ refactored;
2: การทำงานของฟังก์ชั่น หากคุณต้องการพิจารณาว่า OBJ มีการกำหนดหรือสืบทอดชื่อแอตทริบิวต์คุณสามารถตัดสินได้ใน ES5 เช่นนี้: ชื่อใน OBJ;
หรือลบแอตทริบิวต์: ลบ obj [ชื่อ] แม้ว่าสิ่งเหล่านี้จะมีประโยชน์มากสั้นและชัดเจน แต่ก็ต้องถูกห่อหุ้มไว้ในชั้นเรียนเมื่อต้องใช้
ด้วยการไตร่ตรองมันช่วยให้คุณห่อหุ้ม, สะท้อนกลับ (obj, ชื่อ), Reflect.deleteProperty (OBJ, ชื่อ);
3: วิธีการดำเนินการฟังก์ชั่นที่เชื่อถือได้มากขึ้น: ใน ES หากคุณต้องการเรียกใช้ฟังก์ชัน F และส่งชุดพารามิเตอร์ args ไปยังมันและผูกสิ่งนี้คุณต้องเขียนสิ่งนี้:
F.Apply (obj, args)
อย่างไรก็ตามแอปพลิเคชัน F อาจถูกนิยามใหม่เป็นแอปพลิเคชันของผู้ใช้ดังนั้นจึงมีความน่าเชื่อถือมากขึ้นในการเขียนด้วยวิธีนี้:
function.prototype.apply.call (f, obj, args)
รหัสข้างต้นยาวเกินไปและเข้าใจยาก ด้วยการไตร่ตรองเราสามารถสั้นลงและกระชับและชัดเจนยิ่งขึ้น:
Reflect.apply (f, obj, args)
4: ตัวสร้างในรูปแบบพารามิเตอร์ variadic: ลองนึกภาพว่าคุณต้องการสร้างอินสแตนซ์ตัวสร้างผ่านพารามิเตอร์ที่มีความยาวไม่แน่นอน ใน ES5 เราสามารถใช้สัญลักษณ์ส่วนขยายซึ่งสามารถเขียนได้เช่นนี้:
var obj = ใหม่ f (... args)
อย่างไรก็ตามใน ES5 ไม่รองรับอักขระส่วนขยายดังนั้นเราจึงสามารถผ่านพารามิเตอร์ที่แตกต่างกันได้ใน F.Apply หรือ F.Call น่าเสียดายที่ F เป็นตัวสร้างซึ่งเป็นการหลอกลวง แต่ด้วยการไตร่ตรอง
เราสามารถเขียนสิ่งนี้ใน ES5:
var obj = rechersion.construct (f, args)
5: สิ่งนี้ควบคุม accessor หรือ reader: ใน ES5 หากคุณต้องการอ่านแอตทริบิวต์ขององค์ประกอบหรือตั้งค่าแอตทริบิวต์ดังนี้:
var name = ... // รับชื่อคุณสมบัติเป็น stringobj [ชื่อ] // คุณสมบัติทั่วไป lookupobj [ชื่อ] = value // คุณสมบัติทั่วไป
updatereflect.get และ retric.set วิธีการช่วยให้เราสามารถทำสิ่งเดียวกันและเพิ่มพารามิเตอร์พิเศษให้กับ Recciver ช่วยให้เราสามารถตั้งค่า setter ของวัตถุและ getter ขึ้นและลงสิ่งนี้:
var name = ... // รับชื่อคุณสมบัติเป็น stringreflect.get (obj, ชื่อ, wrapper) // ถ้า obj [ชื่อ] เป็น accessor มันจะทำงานด้วย `this === wrapper`reflect.set (obj, ชื่อ, wrapper, accessor ไม่ต้องการใช้วิธีการของตัวเอง }, bar: function () {alert (1);}}; var wrapper = {bar: function () {console.log ("wrapper");}}} revelive.set (obj, "foo", "ค่า", wrapper);6: หลีกเลี่ยงการเข้าถึง __proto__ โดยตรง:
ES5 จัดเตรียม Object.getPrototypeof (OBJ) เพื่อเข้าถึงต้นแบบของวัตถุและ ES6 ยังจัดเตรียมด้วย
Reflect.getPrototypeof (OBJ) และ Reflect.SetPrototypeof (OBJ, NewProto) นี่เป็นวิธีการใหม่ในการเข้าถึงและตั้งค่าต้นแบบของวัตถุ:
ไตร่ตรองการใช้งาน
Reflect.apply เป็นฟังก์ชันจริง prototype.apply () แทนใน ES5 ต้องใช้พารามิเตอร์สามพารามิเตอร์ในการเรียกใช้งานการสะท้อน
พารามิเตอร์แรกคือ: ฟังก์ชันที่จะดำเนินการ;
พารามิเตอร์ที่สองคือ: บริบทที่ต้องดำเนินการ
พารามิเตอร์ที่สามคือ: อาร์เรย์หรือเทียม-อาร์เรย์ซึ่งจะใช้เป็นพารามิเตอร์ในการดำเนินการฟังก์ชัน;
<script> ให้ fn = function () {this.attr = [0,1,2,3];}; ให้ obj = {}; rechorm.apply (fn, obj, []) console.log (obj); การสาธิตของ <script> revelf.apply: <script> rechers.apply (math.floor, undefined, [1.75]); // เอาท์พุท: 1; rechers.apply (String.FromCharcode, undefined, [104, 101, 108, 108, 111]); // เอาท์พุท: "hello" rechorm.apply (regexp.prototype.exec,/ab/, ["confabulation"]). ดัชนี; // เอาท์พุท: 4reflect.apply ("" Charat, "Ponies", [3]); // output: "i" </script> การสะท้อนสามารถใช้ร่วมกับพร็อกซี: {var fn = function () {}; fn.prototype.run = function () {console.log ("วิ่งออกไป"); var proxyfn = new = เป้าหมายใหม่ (... arugments); // วิธีการใช้ rechlect.apply; rechiled.apply (target.prototype.run, obj, arugments); return obj;}}); proxyfn ใหม่ (); // เอาต์พุตก่อน: "Proxy Constructor"; จากนั้นเอาท์พุท: หมดลง} revlect.construct (): rechers.construct เป็นตัวสร้างอินสแตนซ์ มันถูกนำไปใช้ผ่านแบบฟอร์มอาร์กิวเมนต์ วิธีการดำเนินการแตกต่างกัน เอฟเฟกต์นั้นเหมือนกัน พารามิเตอร์แรกของการสร้างคือตัวสร้างและพารามิเตอร์ที่สองคืออาร์เรย์หรือเทียมอาเรย์ที่ประกอบด้วยพารามิเตอร์ วิธีการใช้งานพื้นฐานคือ: var fn = function (arg) {this.args = [arg]}; console.log (ใหม่ fn (1), rechers.construct (fn, [1])); // เอาต์พุตเป็น var d เดียวกัน d = revlem.construct (วันที่, [1776, 6, 4]); d อินสแตนซ์ของวันที่; // trued.getlyear (); // 1776 // reflect.construct และโครงสร้างใหม่เพื่อสะท้อนโครงสร้างและโครงสร้างใหม่เหมือนกันอย่างน้อยจนถึงตอนนี้ ... เราสามารถผ่านพารามิเตอร์ที่สามเพื่อสะท้อนโครงสร้างและพารามิเตอร์ที่สามเป็น superclass องค์ประกอบใหม่จะสืบทอดซูเปอร์คลาสนี้ <script> ฟังก์ชั่น someconstructor () {} var result = reflect.construct (array, [], someconstructor); revel.get.prototypeof (ผลลัพธ์); // someconstructor.prototypearray.isarray (ผลลัพธ์); // true // orvar fn = function () {this.attr = [1];}; var person = function () {}; person.prototype.run = function () {}; console.log var fn = function () {array.apply (สิ่งนี้, อาร์กิวเมนต์); this.shot = () => {console.log ("heheda");};}; var arr = rechersion.construct (fn, []) revlem.defineproperty; Reflect.DefineProperty ส่งคืนค่าบูลีนและค่าแอตทริบิวต์จะถูกเพิ่มลงในวัตถุโดยการกำหนดโดยตรง ส่งคืนวัตถุทั้งหมดหากการเพิ่มล้มเหลวข้อผิดพลาดจะถูกโยนลงไป var obj = {}; obj.x = 10; console.log (obj.x) // เอาต์พุต: 10; เพิ่มมูลค่าโดยใช้ Reflect.defineProperty; <script> var obj = {}; if (rechorm.defineproperty (obj, "x", {value: 7})) {console.log ("เพิ่มความสำเร็จ");} else {console.log ("เพิ่มความสำเร็จ"); Reflect.defineProperty และค่าเท็จจะถูกส่งคืน: var obj = {}; object.preventextensions (obj); object.defineproperty (obj, "x", {ค่า: 101, เขียนได้: เท็จ console.log (rechile.defineproperty (obj, "x", {value: 101})) // return false: หากมีการกำหนดค่าโดยตรงค่าที่กำหนดจะถูกส่งคืนโดยไม่คำนึงว่าค่าถูกกำหนดอย่างถูกต้องเว้นแต่เราจะยืนยันด้วยตนเองว่าค่าคุณสมบัติของวัตถุนั้นประสบความสำเร็จหรือไม่ <script> var obj = {}; object.preventextensions (obj); console.log (obj.aa = 1); // เอาท์พุท: 1; console.log (obj.aa) // เอาท์พุท: undefined; </script> revelf.deleteproperty การใช้งาน: revelf.deleteproperty และ revelf.defineproperty การใช้งานคล้ายกัน ผลการดำเนินงานของ Reflect.deleteProperty และลบ obj.xx เหมือนกัน ความแตกต่างคือแบบฟอร์มการใช้งานแตกต่างกัน: หนึ่งคือตัวดำเนินการและอีกรูปแบบคือการเรียกใช้ฟังก์ชัน Reflect.deleteProperty (Object.freeze ({foo: 1}), "foo"); // falsedelete object.freeze ({foo: 1}). foo; // เอาท์พุท: เท็จ; มีสองพารามิเตอร์ที่จำเป็นสำหรับการใช้วิธี reflect.get (): ครั้งแรกคือวัตถุเป้าหมาย OBJ ที่สองคือวัตถุชื่อแอตทริบิวต์และที่สามเป็นตัวเลือกซึ่งเป็นบริบทของผู้อ่าน (นี้); var obj = {}; obj.foo = 1; console.log (obj.foo); // เอาท์พุท: 1; console.log (revelmet.get (obj, "foo")) // เอาท์พุท: 1; หากสะท้อนกลับมีพารามิเตอร์ที่สามพารามิเตอร์ที่สามจะถูกใช้เป็นบริบทของผู้อ่าน var obj = {"foo": 1, รับ bar () {return this.foo;}}; var foo = {}; foo.foo = "heheda"; console.log (rechorm.get (obj, "bar", foo)); Reflect.getOwnPropertyDescriptor ({x: "hello"}, "x"); // คุณยังสามารถรับได้เช่นนี้: object.getownpropertydescriptor ({x: "1"}, "x"); // ความแตกต่างระหว่างสองสิ่งนี้ // โยน object.getownpropertydescriptor ("สวัสดี", 0); // output: {value: "h", เขียนได้: เท็จ, enumerable: จริง, กำหนดค่าได้: false} revel.getPrototypeof () การใช้วิธี: revel.getPrototypeof และ Object.getPrototypeof เหมือนกัน // เอาต์พุต: Object.prototypereflect.getPrototypeof (Object.prototype); // เอาต์พุต: nullReflect.getPrototypeof (Object.create (null)); // เอาท์พุท: nullReflect. มีวิธีการใช้ reclem.has เป็นเหมือนตัวดำเนินการ: ในตัวอย่าง: xx ใน obj; <script> rechorm.has ({x: 0}, "x") // เอาท์พุท: จริง; Reflect.has ({y: 0}, "y") // output: true; var obj = {x: 0}; console.log ("x" ใน obj); var proxy = new proxy (obj, {มี: function (target, args) {console.log ("Execute Has Method"); return retreh.has (เป้าหมาย, ... args);}}); console.log ("x" ในพร็อกซี); // เอาท์พุท: จริง; console.log (rechers.has (พร็อกซี, "x")) // output: true; </script> OBJ ของการสาธิตนี้เทียบเท่ากับการเป็นวิธีการมันไร้ประโยชน์มันแค่ใช้วิธีการของมัน: obj = พร็อกซีใหม่ ({}, {มี (t, k) {return k.startswith ("ประตู");}}); Reflect.has (obj, "doorbell"); // truereflect.has (obj, "หอพัก"); // falsereflect.isextensible () ใช้ // ตอนนี้องค์ประกอบนี้สามารถขยายได้; var empty = {}; rechist.isextensible (ว่าง); // === true // ใช้วิธี preventextensions เพื่อป้องกันไม่ให้วัตถุนี้ขยายแอตทริบิวต์ใหม่ Reflect.preventExtensions (ว่าง); Reflect.isextensible (ว่าง); // === FALSE // วัตถุนี้ไม่สามารถขยายแอตทริบิวต์ใหม่และแอตทริบิวต์ที่เขียนได้ยังสามารถเปลี่ยน var sealed = object.seal ({}); rechiled.isextensible (ปิดผนึก); // === FALSE // วัตถุนี้ถูกแช่แข็งอย่างสมบูรณ์ var frozen = object.freeze ({}); rechileD.isextensible (แช่แข็ง); // === FALSE ความแตกต่างระหว่าง Reflect.isextensible และ Object.isextensible คือถ้าพารามิเตอร์ไม่ถูกต้องเราจะโยนสิ่งที่ผิดและอีกอันหนึ่งจะกลับมาจริงหรือเท็จ Reflect.ownkeys () การใช้วิธี: rechiled.ownkeys, วัตถุไม่มีวิธี ouldkeys, rechorm.ownkeysz ฟังก์ชั่นของมันคือการส่งคืนคีย์ของวัตถุ; console.log (rechersion.ownkeys ({"a": 0, "b": 1, "c": 2, "d": 3})); // เอาท์พุท: ["A", "B", "C", "D"] console.log (rechorm.ownkeys ([])); // ["ความยาว"] var sym = symbol.for ("ดาวหาง"); var sym2 = symbol.for ("Meteor"); var obj = {[sym]: 0, "str": 0, "773": 0, "0": 0, [sym2]: 0, "-1": 0, "8": 0, "Second Str": 0}; // เอาท์พุท: /["0", "8", "773", "Str", "-1", "Second Str", สัญลักษณ์ (ดาวหาง), สัญลักษณ์ (Meteor)] สะท้อนให้เห็น ในที่สุดคีย์ของประเภทสัญลักษณ์จะถูกจัดเรียงตามลำดับของการแทรก; การเรียงลำดับเกิดขึ้นเนื่องจากเมื่อคุณกำหนดค่าให้กับแอตทริบิวต์วัตถุกฎการเรียงลำดับของคีย์วัตถุคือหมายเลขแรกในสตริงและในที่สุดข้อมูลของประเภทสัญลักษณ์; วิธีการใช้งานของ retrict.preventextensions (): วัตถุยังมีวิธี preventextensions ซึ่งแตกต่างจากการสะท้อนออกเล็กน้อย preventextensions () หากพารามิเตอร์ Reflect.PreventExtensions ไม่ใช่วัตถุมันจะทำให้เกิดข้อผิดพลาด var empty = {}; rechist.isextensible (ว่าง); // === true // วัตถุหลังจากดำเนินการ preventextensions สามารถแก้ไขได้; Reflect.preventExtensions (ว่าง); Reflect.isextensible (ว่าง); // === Falsereflect.preventextensions (1); // typeError: 1 ไม่ใช่ objectObject.preventextensions (1); // ไม่มีข้อผิดพลาดถูกโยนทิ้งมันจะกลับมา: 1reflect.set () วิธีการสะท้อนกลับ var obj = {}; rechorm.set (obj, "prop", "value"); // เอาท์พุท: TrueConsole.log (obj.prop); // เอาท์พุท: "value" var arr = ["เป็ด", "เป็ด", "เป็ด"]; rechistset.set (arr, 2, "goose"); // trueconsole.log (arr [2]); // "Goose" reflect.set (arr, "ความยาว", 1); // trueconsole.log (arr); // ["duck"]; rechiled.set (obj) เทียบเท่ากับ rechorm.set (obj, undefined, undefined); var obj = {}; rechice // เอาท์พุท: จริง // รหัสข้างต้นเทียบเท่ากับการสะท้อนกลับ (obj, undefined, undefined); rech, getownpropertydescriptor (obj, "undefined"); // {ค่า: ไม่ได้กำหนด, เขียนได้ ค่า) {console.log ("setter"); this.value = value;}, รับ key () {return this.value;}}; retreh.set (obj, "key", "heheda", obj) console.log (obj); มันจะตั้งค่าต้นแบบสำหรับวัตถุซึ่งคือการเปลี่ยนแอตทริบิวต์ __proto__ ของวัตถุ ... ; rechiled.setPrototypeof ({}, object.prototype); // เอาต์พุตจริง // ไปยังอาร์เรย์วัตถุ [[ต้นแบบ]] เป็น null.reflect.setPrototypeof ({}, null); // true // ในเวลานี้ obj .__ proto__ ไม่ได้กำหนด // ฟรีวัตถุและรีเซ็ต [[rototype]] reclem.setPrototypeof (Object.freeze ({}), null); // false // ถ้าห่วงโซ่ต้นแบบขึ้นอยู่กับลูปมันจะส่งคืน false.var target = {}; var proto = object.create (เป้าหมาย); revel.set.setPrototypeof (เป้าหมาย, โปรโต); // เท็จ