5 penemuan JavaScript menarik dibuat dalam kode sumber Vue

Membaca kode sumber dari kerangka kerja yang terkenal dapat membantu programmer untuk meningkatkan keterampilan profesionalnya. Penulis artikel, terjemahan yang kami terbitkan hari ini, baru-baru ini menganalisis kode vue2.x. Dia menemukan dalam kode ini beberapa ide JavaScript menarik yang dia putuskan untuk dibagikan kepada semua orang.



1. Menentukan jenis yang tepat dari objek apa pun


Seperti yang kita semua tahu, dalam JavaScript ada enam tipe data primitif ( Boolean, Number, String, Null, Undefined, Symbol), dan satu jenis objek - Object. Apakah Anda tahu cara membedakan antara jenis nilai objek yang berbeda? Objek bisa berupa array atau fungsi, bisa berupa kumpulan nilai Mapatau sesuatu yang lain. Apa yang perlu dilakukan untuk mengetahui jenis objek yang tepat?

Sebelum mencari jawaban untuk pertanyaan ini, mari kita pikirkan perbedaan antara Object.prototype.toString.call(arg)dan String(arg).

Penggunaan ekspresi ini bertujuan untuk mengubah parameter yang diteruskan ke mereka menjadi string. Tetapi mereka bekerja secara berbeda.

Saat dipanggil, String(arg)sistem akan mencoba menelepon arg.toString()atau arg.valueOf(). Akibatnya, jika dalam argatau dalam prototipeargmetode ini akan ditimpa, panggilan Object.prototype.toString.call(arg)dan String(arg)akan memberikan hasil yang berbeda.

Pertimbangkan sebuah contoh.

const _toString = Object.prototype.toString
var obj = {}
obj.toString()  // [object Object]
_toString.call(obj) // [object Object]

Kami akan menjalankan kode ini di konsol alat pengembang browser.


Dalam hal ini panggilan obj.toString()dan hasil Object.prototype.toString.call(obj)mengarah ke yang sama.

Ini adalah contoh lain.

const _toString = Object.prototype.toString
var obj = {}
obj.toString = () => '111'
obj.toString()  // 111
_toString.call(obj) // [object Object]
/hello/.toString() // /hello/
_toString.call(/hello/) // [object RegExp]

Ayo jalankan kode di konsol.


Sekarang, memanggil metode objek .toString()dan menggunakan konstruk Object.prototype.toString.call(obj)memberikan hasil yang berbeda.

Berikut adalah aturan yang menggambarkan perilaku metode dalam standar skrip ECMAS Object.prototype.toString().


Deskripsi metode Object.prototype.toString () dalam standar ECMAScript

Melihat dokumentasi, kita dapat menyimpulkan bahwa ketika dipanggilObject.prototype.toString()untuk objek yang berbeda, hasil yang berbeda akan dikembalikan.

Jelajahi ide ini di konsol.


Selain itu, nilai yang dikembalikan Object.prototype.toString()selalu disajikan dalam format berikut:

β€˜[object ’ + β€˜tag’ +β€˜] ’

Jika kita perlu mengekstrak hanya bagian dari konstruksi ini tag, kita bisa sampai ke bagian ini dengan menghapus karakter yang tidak perlu dari awal dan akhir baris menggunakan ekspresi atau metode biasa String.prototype.slice().

function toRawType (value) {
    const _toString = Object.prototype.toString
    return _toString.call(value).slice(8, -1)
}
toRawType(null) // "Null"
toRawType(/sdfsd/) //"RegExp"

Jelajahi fitur ini di konsol.


Seperti yang Anda lihat, menggunakan fungsi di atas Anda dapat menemukan tipe variabel objek yang tepat.

β†’ Di sini , di repositori Vue, Anda dapat menemukan kode untuk fungsi serupa.

2. Caching hasil fungsi


Misalkan ada fungsi yang mirip dengan yang berikut ini yang melakukan perhitungan panjang:

function computed(str) {    
    console.log('2000s have passed')
    return 'a result'
}

Dengan membuat fungsi seperti itu, kami bermaksud melakukan cache hasil yang dikembalikan padanya. Ketika fungsi ini dipanggil lain kali, dengan memberikan parameter yang sama seperti sebelumnya, kode fungsi "berat" tidak akan dieksekusi. Sebagai gantinya, hasil yang di-cache akan dikembalikan, tanpa waktu tambahan. Bagaimana cara melakukannya?

Anda dapat, misalnya, menulis fungsi pembungkus untuk fungsi objektif. Fungsi seperti itu dapat diberi nama cached. Fungsi ini menerima, sebagai argumen, fungsi objektif, dan mengembalikan fungsi baru yang dilengkapi dengan kemampuan caching. Dalam fungsi ini, cachedAnda dapat menyimpan hasil panggilan sebelumnya ke fungsi target menggunakan entitas Objectatau Map. Berikut adalah kode untuk fungsi ini:

function cached(fn){
  //     ,      
  const cache = Object.create(null);

  //      
  return function cachedFn (str) {

    //       -   
    if ( !cache[str] ) {
        let result = fn(str);

        //      
        cache[str] = result;
    }

    return cache[str]
  }
}

Berikut adalah contoh penggunaan fungsi di atas.


β†’  Ini adalah kode untuk fungsi serupa yang tersedia di basis kode Vue.

3. Konversi string bentuk hello-world ke string bentuk helloWorld


Ketika beberapa programmer bekerja bersama dalam proyek yang sama, sangat penting bagi mereka untuk menjaga gaya kode yang seragam. Seseorang, misalnya, dapat merekam beberapa pengidentifikasi komposit dalam suatu format helloWorld, dan seseorang dalam suatu format hello-world. Untuk menertibkan area ini, Anda dapat membuat fungsi yang mengubah hello-worldbaris tampilan menjadi baris helloWorld.

const camelizeRE = /-(\w)/g
const camelize = cached((str) => {
  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
camelize('hello-world')
// "helloWorld"

β†’ Ini adalah tempat kode Vue dari mana contoh ini berasal.

4. Menentukan lingkungan mana kode JavaScript dijalankan


Saat ini, mengingat perkembangan browser yang cepat, kode JavaScript dapat dieksekusi di berbagai lingkungan. Untuk lebih menyesuaikan proyek dengan lingkungan yang berbeda, Anda harus dapat menentukan di mana program dijalankan:

const inBrowser = typeof window !== 'undefined'
const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
const UA = inBrowser && window.navigator.userAgent.toLowerCase()
const isIE = UA && /msie|trident/.test(UA)
const isIE9 = UA && UA.indexOf('msie 9.0') > 0
const isEdge = UA && UA.indexOf('edge/') > 0
const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
const isPhantomJS = UA && /phantomjs/.test(UA)
const isFF = UA && UA.match(/firefox\/(\d+)/)

β†’ Di sinilah saya menemukan kode ini.

5. Perbedaan antara fungsi bawaan dan fungsi yang ditentukan pengguna


JavaScript dikenal memiliki dua jenis fungsi. Tipe pertama adalah built-in, atau, sebagaimana mereka juga disebut, fungsi "asli". Fungsi-fungsi tersebut disediakan oleh lingkungan di mana kode dijalankan. Tipe kedua adalah apa yang disebut "fungsi pengguna", yaitu, yang ditulis sendiri oleh pemrogram. Anda dapat membedakan antara fungsi-fungsi ini, dengan mempertimbangkan fakta bahwa, ketika mengubahnya menjadi string, berbagai hasil dikembalikan.

Array.isArray.toString() // "function isArray() { [native code] }"
function fn(){} 
fn.toString() // "function fn(){}"

Kami akan bereksperimen dengan kode ini di konsol.


Metode toString()fungsi asli selalu mengembalikan konstruksi dari bentuk berikut:

function fnName() { [native code] }

Mengetahui hal ini, Anda dapat menulis fungsi yang memungkinkan Anda membedakan antara fungsi asli dan fungsi yang ditentukan pengguna:

function isNative (Ctor){
  return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
}

β†’  Ini adalah tempat di basis kode Vue di mana ada fungsi seperti itu.

Apakah Anda berhasil menemukan sesuatu yang menarik dengan menjelajahi kode di repositori proyek JavaScript terkenal?


All Articles