Mengapa ada kode JavaScript yang ingin "memotong ikatan"?

10

Alasan menggunakan a

(0, foo.fn)();

adalah untuk memotong ikatan : thistidak akan lagi terikat footetapi akan terikat pada objek global.

Tapi apa alasannya mengapa setiap kode JavaScript (atau kode JS Google) ingin memotong ikatannya? (dan apakah itu anti-pola atau tidak?)

nonopolaritas
sumber
menyebutnya mengikat tidak terasa benar. bindmetode mengikat. Ini hanya perubahan konteks. Anda tidak dapat memotong atau kehilangan ikatan (ikatan dibuat oleh bind).
marzelin
mungkin kode ini dihasilkan oleh transpiler dari beberapa bahasa fungsional (clojurescript?) yang memiliki persyaratan khusus ketika datang ke fungsi panggilan?
marzelin
kemungkinan rangkap dari Mengapa babel menulis ulang fungsi yang diimpor memanggil ke (0, fn) (...)? - atau di mana lagi Anda melihat ini?
Bergi
Saya pikir saya melihatnya dalam kode Google dan mungkin dalam beberapa kerangka kerja seperti Angular, React, atau yang lainnya ... tidak dapat mengingat di mana dan kadang-kadang
diperkecil

Jawaban:

8

Jenis kode ini biasanya dihasilkan oleh transpiler (seperti Babel), untuk mengkonversi JavaScript modern - yang menggunakan tambahan spesifikasi terbaru - ke versi JavaScript yang lebih banyak didukung.

Berikut adalah contoh di mana pola transpilasi ini terjadi:

Katakanlah kita memiliki kode asli ini sebelum transpilasi:

import {myfunc} from "mymodule";
myfunc();

Untuk membuat kode yang kompatibel dengan ES5 ini, Anda dapat melakukan ini:

"use strict";    
var mymodule = require("mymodule");    
mymodule.myfunc();

Tetapi di sini kita akan mengeksekusi myfuncdengan mymodulesebagai thisnilai, yang tidak terjadi dalam kode asli. Dan meskipun itu mungkin tidak selalu menjadi masalah, lebih baik untuk memastikan fungsi berperilaku seperti itu dalam versi asli , bahkan jika fungsi itu akan menggunakan thisreferensi - seberapa tidak biasa atau bahkan tidak berguna penggunaan thisdalam myfuncmungkin ( karena juga dalam versi aslinya akan undefined).

Jadi misalnya, jika kode asli akan melempar kesalahan karena this.memberFun()referensi dalam fungsi, itu juga akan membuang dalam versi yang diubah.

Jadi begitulah operator koma digunakan untuk menyingkirkan perbedaan itu:

(0, mymodule.myfunc)();

Memang, dalam kode yang Anda tulis sendiri, Anda tidak akan pernah memiliki kasus penggunaan yang baik untuk pola ini, karena Anda tidak akan menggunakan thisdi myfuncdi tempat pertama.

trincot
sumber
Bagaimana requirehubungannya dengan ES6 atau ES5? Dulu saya pikir yang diperlukan adalah modul simpul.
connexo
requirememang fungsi yang tersedia di node atau disediakan di perpustakaan seperti browserify, require.js, ... dll. Ini tidak secara spesifik terkait dengan ES5 / 6. Di sisi lain, konstruksi bahasa ES6 + suka importtidak dapat di-backport ke ES5 tanpa sesuatu seperti transpilasi.
trincot
jadi jika mengkondisikannya ke beberapa baris ringkasan: jika itu adalah pustaka atau modul yang mencakup banyak fungsi yang tidak benar-benar metode atau OO, (dalam bentuk modA.fn1), maka fungsi-fungsi ini benar-benar tidak boleh digunakan thistetapi jika secara tidak sengaja mereka melakukannya, kami tidak ingin thismemengaruhi modul dengan cara apa pun sebagai efek samping, jadi kami memotong pengikatannya, membuatnya berperilaku bagaimana seharusnya berperilaku jika itu adalah fungsi independen
nonopolaritas
Ya, memang begitulah cara Anda meringkasnya. Sekali lagi, ini sebagian besar menjadi perhatian bagi transponder, bukan pengatur kode.
trincot