เหตุใดเราจึงสามารถลบคุณสมบัติภายในของวัตถุทั่วโลกได้


12

ฉันอ่าน es5 ในวันนี้และพบว่าแอตทริบิวต์ [[กำหนดค่าได้]] ในคุณสมบัติบิวด์อินบางตัวของออบเจ็กต์ทั่วโลกถูกตั้งค่าเป็นจริงซึ่งหมายความว่าเราสามารถลบคุณสมบัติเหล่านี้ได้

ตัวอย่างเช่น:

วิธีการเข้าร่วมของวัตถุ Array.prototype มีคุณสมบัติ

{[[Writable]]:true, [[Enumerable]]: false, [[Configurable]]: true}

ดังนั้นเราสามารถลบวิธีการเข้าร่วมสำหรับ Array ได้อย่างง่ายดายเช่น:

delete Array.prototype.join;
alert([1,2,3].join);

การแจ้งเตือนจะแสดงundefinedในโครเมียม 17 ของฉัน firefox 9 คือ 10 แม้แต่ ie6;

ใน Chrome 15 & ซาฟารี 5.1.1 แอตทริบิวต์ [[กำหนดค่าได้]] ถูกตั้งค่าเป็นจริงและผลลัพธ์การลบก็เป็นจริงเช่นกัน แต่ผลลัพธ์สุดท้ายยังคงfunction(){[native code]}อยู่ ดูเหมือนว่านี่เป็นข้อผิดพลาดและโครเมียมแก้ไขได้

ฉันไม่ได้สังเกตสิ่งนั้นมาก่อน ในความคิดของฉันลบฟังก์ชั่นในตัวในรหัสผู้ใช้เป็นอันตรายและจะทำให้เกิดข้อบกพร่องมากมายเมื่อทำงานกับผู้อื่นดังนั้นทำไม ECMAScript ตัดสินใจเรื่องนี้?


คำตอบหลายคำยกย่องความสามารถในการปรับแต่งฟังก์ชั่นในตัวด้วยการลบคุณสมบัติ แต่วิธีการนี้มีความจำเป็นเท่านั้นเพราะฟังก์ชั่นดังกล่าวมีการเดินสายในตัวแปรทั่วโลกแทนที่จะใช้ DI ดูเหมือนว่าการปรับแต่งโดยการลบคุณสมบัติคือแฮ็คที่มีการออกแบบที่ไม่ดีอย่างลึกซึ้ง ตัวอย่างเช่นหากคุณจำเป็นต้องเปลี่ยน JSON parser คุณสามารถเขียนโค้ดที่ใช้ JSON parser เป็นอินพุต
Reinstate Monica

คำตอบ:


2

ฉันจะมีแนวโน้มที่จะเห็นด้วยกับคุณ แต่ในทางกลับกันฉันเพิ่งพบสถานการณ์ที่ผมจำเป็นต้องไปdelete JSON.stringifyในบางสถานการณ์เนื่องจากมีข้อผิดพลาดใน Firefox 3.5 แน่นอนฉันดีใจที่มีความสามารถในการสร้างตัวลิงที่นั่น


ทำไมคุณไม่ลองเขียนทับมันล่ะ?
demix

2
เนื่องจากสิ่งต่อไปที่เกิดขึ้นคือ JSON2.js ถูกโหลดซึ่งตรวจจับการมีอยู่ของJSON.stringifyและฉีดมันหากจำเป็น ขอโทษฉันไม่ได้อธิบายว่าในคำตอบของฉัน
N3dst4

ดังนั้นคุณสามารถแก้ไขซอร์สโค้ดของ JSON2.js ได้เช่นกัน lol
demix

เป็นความคิดที่ดีที่จะแก้ไขไลบรารีของบุคคลที่สามเพราะคุณไม่สามารถอัปเกรดได้โดยไม่คัดลอกการเปลี่ยนแปลงทั้งหมดของคุณ
N3dst4

1

การกำหนดค่าไม่ได้เกี่ยวกับการลบ

มันเกี่ยวกับความสามารถในการแทนที่ค่าแบบอ่านอย่างเดียว

มันเป็นเครื่องมือที่ทรงพลังมากและค่าที่ไม่สามารถกำหนดค่าได้นั้นน่าผิดหวังหากคุณไม่สามารถลบได้

ฉันมีบางกรณีที่ฉันต้องการแก้ไขข้อบกพร่องที่คลุมเครือหรือฉีดฟังก์ชันการทำงานที่แตกต่างกันเล็กน้อย (การสกัดกั้นการบันทึก) การทำเช่นนั้นต้องการการแทนที่ค่า

ตัวอย่าง:

Object.defineProperty(Object.prototype, "foo", {
  value: 42,
  configurable: true
});

var o = {};
o.foo = 50; // fails. foo is not writable
delete Object.prototype.foo;
o.foo = 50; // succeeds
/* optionally put Object.prototype.foo back */

แนวคิดทั้งหมดคือถ้าคุณสามารถลบคุณสมบัติคุณมีการควบคุมการเขียนโปรแกรมเมตาเพิ่มเติม หากคุณไม่สามารถลบพวกเขาได้คุณจะรำคาญภาษา

ไม่มีเหตุผลที่ดีที่จะทำให้คนอื่นไม่สามารถลบคุณสมบัติแล้วทำให้คนอื่นรำคาญได้


1
แอตทริบิวต์ [[เขียนได้]] ควบคุมความสามารถในการเปลี่ยนค่าใน ES5: [[เขียนได้]] บูลีนหากเป็นเท็จให้ลองด้วยรหัส ECMAScript เพื่อเปลี่ยนคุณสมบัติ [[ค่า]] ของคุณสมบัติโดยใช้ [[ใส่]] จะไม่สำเร็จ . [[กำหนดค่าได้]] บูลีนหากเป็นเท็จพยายามลบคุณสมบัติเปลี่ยนคุณสมบัติให้เป็นคุณสมบัติผู้เข้าถึงหรือเปลี่ยนคุณสมบัติ (นอกเหนือจาก [[ค่า]])
demix

@demix ใช่ว่าเป็นที่ถูกต้อง ...
Raynos

0

.. การลบฟังก์ชันในตัวในรหัสผู้ใช้เป็นอันตราย

ค่อนข้างตรงกันข้าม การอนุญาตการปรับแต่งนั้นดีเพราะช่วยให้ผู้เขียนเว็บไซต์มีความยืดหยุ่นมากขึ้น

หากผู้เขียนเว็บไซต์ต้องการโหลดรหัสบุคคลที่สามภายใน JS VM เดียวกันและต้องการใช้ตัวแยกวิเคราะห์ inbuilt JS เพื่อทำเช่นนั้นเขาสามารถรักษาความปลอดภัยคุณสมบัติโดยการตั้งค่าพวกเขาเป็นไม่สามารถกำหนดค่าก่อนที่จะโหลดรหัสบุคคลที่สาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.