underscorejs - apa perbedaan antara extendOwn vs extend?

Saat menelusuri daftar metode underscorejs, saya tidak bisa tidak memperhatikan metode yang saya tidak ingat pernah ada di sana sebelumnya: extendOwn

dokumentasi untuk metode ini menyatakan sebagai berikut:

extendOwn _.extendOwn(tujuan, *sumber) Alias: assign

Seperti perluasan, tetapi hanya menyalin properti milik ke objek tujuan.

Saya memahami cara .extend() digunakan dan apa fungsinya... tetapi demi kehidupan saya, saya tidak dapat memahami perbedaannya dengan .extendOwn().

Saya mencoba menggunakan .extend() lalu .extendOwn() untuk memperluas beberapa objek hanya untuk melihat apakah mungkin ada sesuatu yang jelas akan terjadi - namun keduanya tampaknya menghasilkan hasil yang sama.

var a = {
    foo: false
};

var b = {
    bar: true
};

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

Setiap wawasan tentang misteri ini akan sangat dihargai!


person Jonathon Hibbard    schedule 12.03.2015    source sumber
comment
Saya belum - itu ide yang bagus, terima kasih   -  person Jonathon Hibbard    schedule 13.03.2015
comment
heh, jadi aku baca saja sumbernya. Lucunya, hal ini bermuara pada penggunaan .keys vs _.allKeys - yang pada gilirannya berbeda, ada yang menggunakan nativeKeys dan yang berikut ini : for (var key in obj) if (.has(obj, kunci)) kunci.push(kunci); dimana yang lainnya tidak. tak tahu - sepertinya masih menjadi misteri bagi saya mengapa extendOwn diperlukan.   -  person Jonathon Hibbard    schedule 13.03.2015


Jawaban (2)


"Properti sendiri" adalah istilah teknis di JS. Properti suatu objek adalah properti yang tidak diwarisinya.

Berikut cuplikan singkat yang memperlihatkan perbedaan perilaku extend dan 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

Seperti yang Anda lihat, extendOwn hanya menyalin properti yang ditentukan langsung pada sumbernya, sedangkan extend juga menyalin properti yang ditentukan di sepanjang rantai prototipenya. Perhatikan juga simetri dengan _.has:

_.has(plane, 'width')   // true
_.has(plane, 'length')  // false
person johncip    schedule 04.03.2016
comment
Jawaban ini sangat membantu. Dokumentasi Garis Bawah sangat buruk dalam menjelaskan hal ini. - person luxon; 14.12.2016

Jadi bagi siapa pun yang bertanya-tanya, tempat yang tepat untuk menemukan jawabannya ada di sini: https://github.com/jashkenas/underscore/search?q=extendOwn&type=Issues&utf8=%E2%9C%93

Perbarui

Bagi siapa pun yang tertarik, jawabannya adalah extendOwn identik dengan Object.assign dengan implementasinya sedikit berbeda. Underscorejs hanya menambahkan alternatif ke dalamnya. Daripada mengganti assign dengan implementasi baru ke Underscorejs dan menyebutnya _.assign, mereka menyebutnya _.extendOwn (dengan _.assign menjadi alias _.extendOwn).

Alasan konvensi penamaan ini dapat dimengerti, tetapi agak membingungkan. Anda lihat, Object.assign adalah nama resmi ES6 untuk metode/logika yang kita kenal sebagai "extend" (seperti yang disebut oleh alat seperti jQuery dan Underscore).

Keputusan tim Garis Bawah adalah mereka memutuskan untuk memanggil tim utama / metode induk extendOwn untuk mematuhi standar internal mereka sendiri. Memberi nama metode utama _.assign akan menjadi (bagi tim Garis Bawah) yang berlawanan dengan intuisi mereka, hal ini membingungkan apa yang dilakukan "extend". Dengan menyebutnya extendOwn, mereka mengatakan bahwa metode ini melakukan hal yang sama seperti "memperluas" tetapi didasarkan pada implementasi fungsi ES6 yang dikenal sebagai "menetapkan".

Pada dasarnya - apa yang mereka alami di sini adalah sebuah paradoks, dan mereka perlu mengambil keputusan. Entah mereka tetap berpegang pada konvensi yang kita kenal sebagai "extend" atau mereka mengizinkan "assign" - yang hanya akan bertentangan dengan nama aslinya (yang mungkin juga mulai menyebabkan orang mempertanyakan mengapa mereka masih menyebut metode lain "extend" daripada assignSomethinghere sebagai gantinya).

Singkat cerita - extendOwn adalah versi Garis Bawah dari Object.assign ES6. Mereka hanya menamakannya extendOwn agar tetap selaras dengan konvensi penamaan yang sama, yaitu diberi nama extend.

person Jonathon Hibbard    schedule 12.03.2015