ขีดล่าง js - ความแตกต่างระหว่าง extendOwn กับการขยายคืออะไร?

ในขณะที่ดูรายการวิธีการของ underscorejs ฉันก็อดไม่ได้ที่จะสังเกตเห็นวิธีการที่ฉันจำไม่ได้ว่าอยู่ที่นั่น ก่อน: extendOwn

เอกสารประกอบสำหรับวิธีนี้ ระบุสิ่งต่อไปนี้:

extendOwn _.extendOwn(destination, *sources) นามแฝง: มอบหมาย

ชอบขยาย แต่คัดลอกเฉพาะคุณสมบัติ own ไปยังวัตถุปลายทางเท่านั้น

ฉันเข้าใจวิธีใช้ .extend() และทำหน้าที่อะไร... แต่ตลอดชีวิตของ ฉัน ฉันไม่เข้าใจว่ามันแตกต่างจาก .extendOwn() อย่างไร

ฉันลองใช้ .extend() จากนั้นจึงใช้ .extendOwn() เพื่อขยายวัตถุบางส่วนเพื่อดูว่าอาจมีบางสิ่งที่ชัดเจนเกิดขึ้นหรือไม่ แต่ดูเหมือนว่าทั้งสองวัตถุจะให้ผลลัพธ์เดียวกัน

var a = {
    foo: false
};

var b = {
    bar: true
};

// This will produce { foo: false, bar: true }; ..just like _.extend() would =\
_.extendOwn( a, b );

ความเข้าใจอย่างลึกซึ้งเกี่ยวกับความลึกลับนี้จะได้รับการชื่นชมอย่างมาก!


person Jonathon Hibbard    schedule 12.03.2015    source แหล่งที่มา
comment
ฉันยังไม่มี - นั่นเป็นความคิดที่ดี ขอบคุณ   -  person Jonathon Hibbard    schedule 13.03.2015
comment
เฮ้ฉันเพิ่งอ่านแหล่งที่มา สิ่งที่ตลกก็คือมันต้องใช้ .keys vs _.allKeys - ซึ่งในทางกลับกันจะใช้ NativeKeys และสิ่งต่อไปนี้: for (var key in obj) if (.has(obj, คีย์)) คีย์กด (คีย์); โดยที่อีกฝ่ายไม่มี ไม่รู้ - ดูเหมือนจะยังเป็นปริศนาสำหรับฉันอยู่บ้างว่าทำไม ExtendedOwn ถึงมีความจำเป็น   -  person Jonathon Hibbard    schedule 13.03.2015


คำตอบ (2)


"คุณสมบัติของตัวเอง" เป็นคำศัพท์ทางเทคนิคใน JS คุณสมบัติของวัตถุนั้นเป็นคุณสมบัติของวัตถุที่ไม่ได้รับการสืบทอด

ต่อไปนี้เป็นตัวอย่างสั้นๆ ที่แสดงพฤติกรรมที่แตกต่างกันของ extend และ extendOwn:

// lines have length
line = { length: 4 }

// planes have width and inherit length
plane = Object.create(line)
plane.width = 5
plane.length  // 4

// making a cube object, using extend
cube = _.extend({ height: 6 }, plane)
cube.length  // 4

// making a cube object, using extendOwn
notACube = _.extendOwn({ height: 6 }, plane)
notACube.length  // undefined

อย่างที่คุณเห็น extendOwn คัดลอกเฉพาะคุณสมบัติที่กำหนดไว้โดยตรงบนแหล่งที่มา ในขณะที่ extend ยังคัดลอกคุณสมบัติที่กำหนดไว้ตามสายโซ่ต้นแบบด้วย โปรดสังเกตความสมมาตรด้วย _.has:

_.has(plane, 'width')   // true
_.has(plane, 'length')  // false
person johncip    schedule 04.03.2016
comment
คำตอบนี้มีประโยชน์ เอกสารขีดเส้นใต้อธิบายเรื่องนี้ได้แย่มาก - person luxon; 14.12.2016

ดังนั้นสำหรับทุกคนที่สงสัย สถานที่ที่ดีในการค้นหาคำตอบอยู่ที่นี่: https://github.com/jashkenas/underscore/search?q=extendOwn&type=Issues&utf8=%E2%9C%93

อัปเดต

สำหรับผู้ที่สนใจ คำตอบก็คือ extendOwn มีความหมายเหมือนกันกับ Object.assign ด้วย การใช้งานจะแตกต่างออกไปเล็กน้อย ขีดล่าง js เพียงเพิ่มทางเลือกเข้าไป แทนที่จะแทนที่ assign ด้วยการใช้งานใหม่ใน Underscorejs และเรียกมันว่า _.assign พวกเขากำลังเรียกมันว่า _.extendOwn (โดยที่ _.assign เป็นนามแฝงของ _.extendOwn)

เหตุผลของการตั้งชื่อแบบแผนการตั้งชื่อนี้เป็นเรื่องที่เข้าใจได้ แต่ฉันก็ค่อนข้างสับสนเล็กน้อย คุณจะเห็นว่า Object.assign เป็นชื่ออย่างเป็นทางการของ ES6 สำหรับวิธีการ/ตรรกะที่เรารู้จักในชื่อ "extend" (ตามที่เรียกโดยเครื่องมือ เช่น jQuery และ Underscore)

การตัดสินใจของทีม Underscore คือพวกเขาตัดสินใจโทรหาหมายเลขหลัก /parent method extendOwn เพื่อปฏิบัติตามมาตรฐานภายในของตนเอง การตั้งชื่อเมธอดหลัก _.assign จะเป็น (สำหรับทีมของขีดล่าง) ขัดกับสัญชาตญาณสำหรับพวกเขา มันสร้างความสับสนว่า "extend" ทำอะไร ด้วยการเรียกมันว่า extendOwn พวกเขากำลังบอกว่าเมธอดนี้ทำหน้าที่เหมือนกับ "ขยาย" แต่ขึ้นอยู่กับการใช้งานฟังก์ชันนี้ที่เรียกว่า "มอบหมาย" ของ ES6

โดยพื้นฐานแล้ว สิ่งที่พวกเขามีอยู่ที่นี่เป็นสิ่งที่ขัดแย้งกัน และพวกเขาจำเป็นต้องตัดสินใจ ไม่ว่าพวกเขาจะยึดติดกับแบบแผนที่เรารู้จักกันในชื่อ "ขยาย" หรืออนุญาตให้ "มอบหมาย" ซึ่งจะขัดแย้งกับชื่อเดิมนั้น (ซึ่งอาจเริ่มทำให้ผู้คนตั้งคำถามว่าทำไมพวกเขาถึงยังเรียกวิธีอื่นว่า "ขยาย" มากกว่า assignSomethinghere แทน)

เรื่องสั้นขนาดยาว - extendOwn เป็นเวอร์ชันขีดล่างของ Object.assign ของ ES6 พวกเขาตั้งชื่อมันว่า extendOwn เพื่อให้สอดคล้องกับรูปแบบการตั้งชื่อเดียวกันซึ่งมีชื่อว่าขยาย

person Jonathon Hibbard    schedule 12.03.2015
comment
การเรียก _.has ภายในลูป in ที่คุณพูดถึงในความคิดเห็นของคุณอาจเป็นเพียงนามแฝงสำหรับ obj.hasOwnProperty(key) คุณสมบัติ extendOwn ไม่ได้เดินตามต้นแบบ แต่ extend ทำ; จะไม่มีความแตกต่างใด ๆ หากคุณเพียงแค่ใช้วัตถุธรรมดา (เช่น o = { ... }) - person mu is too short; 13.03.2015
comment
นี่ไม่ได้ตอบคำถาม คุณได้ให้รายละเอียดเกี่ยวกับประวัติว่าทำไมสิ่งต่าง ๆ ถึงถูกตั้งชื่อตามที่เป็นอยู่ แต่ไม่ได้อธิบายความแตกต่างในการทำงานระหว่างทั้งสองวิธี - person Max Barraclough; 20.03.2020
comment
อ่านซ้ำอีกครั้ง บทความที่เชื่อมโยงในคำตอบที่ยอมรับ (และในความคิดเห็นด้านบนโดย @muistooshort ) ให้ความยุติธรรมในการอธิบายความแตกต่างของคำถามการใช้งานจริง - person Jonathon Hibbard; 23.03.2020