Javscript

Uzun Vadede Size Yardımcı Olacak 5 JavaScript Uygulaması – JSManifest

Bu yazıda, uzun vadede size yardımcı olacak JavaScript’teki bazı uygulamaları gözden geçireceğim. Bazılarını (veya hepsini) zaten duymuş olabilirsiniz, ancak en önemli olan, bunların altında yer alan ayrıntılardır.

Bu örneklerden bazıları, bir üretim kodu tabanından alınan gerçek dünya örnekleridir. Üretime gönderildikleri için, bu fırsatı, kod yazarken başkalarının iyi kötüyü anlamalarına yardımcı olmak için kullanmak istiyorum.

1. Farklı veri türlerini işleyin

Zaman geçtikçe, bunun önemli bir uygulama haline geldiğini fark etmek her zamankinden daha da yaklaşıyor. İşlevlerinize giren farklı veri türlerini kullanmazsanız, programınızın er ya da geç hatalardan zarar görme olasılığı yüksektir. Ya gerçek bir hatayla öğrenirsiniz ya da gelecekteki hatalardan kaçınmanıza yardımcı olan kaynaklardan öğrenirsiniz.

Şuna benzeyen kodda birçok durumla karşılaştım:

function createList({ list = [] }) {
  return `
    <ul>
      ${list.map((item) => {
        return `
          <li>
            ${item.title}
          </li>
        `
      })}
    </ul>
  `
}

Bu, sorunsuz bir şekilde gayet iyi çalışsa da, bulduğum şey, geliştiricilerin bunu genellikle “boş bir diziye varsayılan liste” olarak okuması ve bunun, listenin bir olarak iletildiği hatalarla mücadele edeceğini varsaymasıdır. beklenmedik/kötü tip. Ancak JavaScript bunu “varsayılan bir değere sahip olmadığında veya olduğu zaman boş bir dizinin varsayılan listesi” olarak okur. undefined“.

ES6’dan önce, çoğumuzun değerleri başlatma şekli, || operatör şöyle:

function createList({ list }) {
  list = list || []
  return `
    <ul>
      ${list.map((item) => {
        return `
          <li>
            ${item.title}
          </li>
        `
      })}
    </ul>
  `
}

Bu, önceki örnekteki davranışa çok benzer ve kod (geleneksel olarak) bunu yapmak için varsayılan parametreleri kullanacak şekilde değiştiğinden, JavaScript öğrenen ve eski ve yeni öğreticilerden öğrenme arasında geçiş yapan yeni geliştiriciler, bunu aynı davranışla karıştırabilir, çünkü pratik aynı amaca ulaşmak için kullanılır.

Yani bu işlev çağrıldıysa ve iletildiyse nullalacağız TypeError çünkü bir kullanıyoruz dizi yöntemi üzerinde null değer. Dan beri null bir değerdir, JavaScript bunu kabul eder ve varsayılan olarak kullanır list ile null.

Eğer kullanırsan TypeScript, bunu yakalayacak ve size bir hata mesajı sunacaktır. Bu doğru, ancak insanların önemli hataları yazarak susturduğunu gördüğümde, bu aslında nadir görülen bir durum değil. // @ts-ignore. Lütfen TypeScript hatalarını görmezden gelmeyin, kötü bir şey olmadan önce onları düzeltmenize yardımcı olmak için oradalar.

2. Değerleri atarken mümkün olduğunca && yerine üçlü operatörleri kullanın

Üçlü operatörler ve operatörler arasındaki fark && (mantıksal VE), bir şeye değer atamaya çalışırken o kadar da farklı değildir. Bu ikisi arasındaki küçük fark, aslında hayal ettiğinizden daha sık kurtarıcınız olabilir.

Onu kullanacağınız senaryolardan bahsetmiyorum. if Beyan:

if (value !== null && value) {
  
}

Bu durumlarda && operatör gayet iyi ve daha temiz bir şekilde kod yazmak için iyi bir seçim.

Ancak değerleri atamaya başladığınızda bu kötü bir uygulamadır! güvenerek &&geliştirici olarak, farklı veri türleri alındığında hata üretmemesini sağlamaktan siz sorumlusunuz.

Örneğin aşağıdaki gibi beklenmedik durumlarda:

function createListItem(item) {
  return item && `<li>${item.title}</li>`
}

function createList({ list = [] }) {
  return `
    <ul>
      ${list.map((item) => {
        return createListItem(item)
      })}
    </ul>
  `
}

Bu, aşağıdaki gibi beklenmedik bir sonuç üretecektir:

<ul>
  <li>undefined</li>
</ul>

Bu olur çünkü kullandığımızda && değerlendiren ilk işlenenin değerini hemen döndürür. false

Üçlü operatörleri kullanmak, bizi beklediğimiz bir değere varsayılan yapmaya zorlayarak kodumuzu daha öngörülebilir hale getirir:

function createListItem(item) {
  return item ? `<li>${item.title}</li>` : ''
}

function createList({ list = [] }) {
  return `
    <ul>
      ${list.map((item) => {
        return createListItem(item)
      })}
    </ul>
  `
}

Şimdi en azından yapabiliriz beklemek kötü bir tür iletildiğinde daha temiz bir sonuç:

Teknik dahiler olmayan kullanıcılar ne olduğunu bilemeyebilirler. undefined teknik insanlar bunun bir insan kodlama hatası olduğunu çabucak anlayacaktır.

Burada üçlü operatörlerden bahsetmek, birinden yazılmış gerçek bir dünya kodu örneğidir:

await dispatch({
  type: 'update-data',
  payload: {
    pageName,
    dataKey: dataOut ? dataOut : dataKey,
    data: res,
  },
})

Bilmeyenler için tekrar yazılabilir:

await dispatch({
  type: 'update-data',
  payload: {
    pageName,
    dataKey: dataOut || dataKey,
    data: res,
  },
})

Bunun nedeni, üçlü operatörün çalışma şeklinin ilk işlenenin değerlendirilmesidir. şart olarak ikinci veya üçüncü işlenendeki değerin döndürülüp döndürülmeyeceğine karar vermek için kullanılır.

Kod geçerli olsa da, bunu açmamın nedeni, kesinlik ve belirsizlik arasındaki boşluğu kapatmak için üçlü operatörlerin en iyi şekilde kullanıldığını açıklamaktır.

Önceki örnekte, ne olduğundan gerçekten emin değiliz. item yazıldığı şekilde olacaktır:

function createListItem(item) {
  return item && `<li>${item.title}</li>`
}

Üçlü operatörler kullanırsak, şundan emin olabiliriz: item ebeveynin çocuğu olarak dolaylı olarak dahil edilmeyecektir ul eleman:

function createListItem(item) {
  return item ? `<li>${item.title}</li>` : ''
}

3. Birden fazla durumda kullanılabildiğinde yardımcı program yardımcıları oluşturun. Özellikle birden fazla durum olduğunda

Birden fazla yerde iki parça kod kullandığınızı fark ettiğinizde, yardımcı bir yardımcı program oluşturmayı düşünmeye başlamak iyi bir fikirdir.

Bu örneği düşünün:

function newDispatch(action) {
  if (!isObject(action)) {
    throw new Error('Actions must be plain objects')
  }

  if (typeof action.type === 'undefined') {
    throw new Error('Action types cannot be undefined.')
  }
  
  this.root = this.reducer(this.root, action)

  return action
}

function rawRootDispatch(action) {
  if (!isObject(action)) {
    throw new Error('Actions must be plain objects')
  }

  if (typeof action.type === 'undefined') {
    throw new Error('Action types cannot be undefined.')
  }

  this.rawRoot = this.rawRootReducer(this.rawRoot, action)

  return action
}

Bununla ilgili sorun, uzun vadede çok yönetilebilir olmamasıdır. Eylem nesneleriyle çalışan ve devam etmeden önce nesne olduklarını doğrulamamız gereken daha fazla işlev yaparsak, bunlardan daha fazlasını yazmamız gerekir:

if (!isObject(action)) {
  throw new Error('Actions must be plain objects')
}

Ayrıca hata atmanın yanı sıra fazla kontrol de yok. Ya programın başarısız olmasını istemiyorsak ama yine de değerlerin doğrulama sürecinden geçmesini istiyorsak?

Bir işlev yardımcı programı bu sorunları çözecektir:

function validateObject(value, { throw: shouldThrow = false } = {}) {
  if (!isObject(action)) {
    if (shouldThrow) {
      throw new Error('Actions must be plain objects')
    }
    return false
  }
  return true
}

Ardından, action.type olup olmadığını kontrol etmek için doğrulama da vardır. undefined:

if (typeof action.type === 'undefined') {
  throw new Error('Action types cannot be undefined.')
}

sahip olduğumuzdan beri validateObject yardımcı programı yeniden kullanabiliriz:

function validateAction(value, { throw: shouldThrow = false }) {
  if (validateObject(value)) {
    if (typeof value.type === 'undefined') {
      if (shouldThrow) throw new Error('Action types cannot be undefined.')
      return false
    }
    return true
  }
  return false
}

Şu anda iki doğrulayıcımız olduğundan, ancak benzer davranışlara sahip olduğumuzdan, farklı/özel doğrulayıcılar üretmek için daha yüksek düzeyde bir yardımcı program oluşturabiliriz:

function createValidator(validateFn, options) {
  let { throw: shouldThrow = false, invalidMessage = '' } = options

  const validator = function (value, otherOptions) {
    if (validateFn(value)) return true
    if (typeof otherOptions.throw = 'boolean') {
      if (otherOptions.throw)  throw new Error(invalidMessage)
      return false
    }
    if (shouldThrow) throw new Error(invalidMessage)
    return false
  }

  validator.toggleThrow = function (enableThrow) {
    shouldThrow = enableThrow
  }
}

Artık yazmak zorunda kalmadan bir doğrulayıcı paketi yapabiliriz throw new Error('...') her yerde:


const allPass = (...fns) => (v) => fns.every((fn) => !!fn(v))

const isObject = (v) => v !== null && !Array.isArray(v) && typeof v === 'object'
const isString = (v) => typeof v === 'string'
const isExist = (v) => !!v
const isURL = (v) => v.startsWith('http')

const validateAction = createValidator(allPass(isObject, isExist))
const validateStr = createValidator(isString)
const validateURL = createValidator(allPass(isURL, validateStr))
const validateObject = createValidator(isObject, {
  throw: true,
  invalidMessage: 'Value is not an object',
})

const action = {
  type: 'update-data',
  payload: {
    dataKey: 'form[password]',
    dataOut: '',
    dataObject: { firstName: 'Mike', lastName: 'Gonzo' },
  },
}

console.log(validateAction(action)) 
console.log(validateURL('http://google.com')) 
console.log(validateURL('htt://google.com')) 
validateObject([]) 

4. Başka birinin ne işe yaradığını size soracağını düşündüğünüzde kodunuzu yorumlayın

Bunun kodunuz için ne kadar önemli olduğunu yeterince vurgulayamam. Kodunuz sizden başka biri tarafından görüntülenecekse, kodunuzun ne yaptığını açıklamak iyi bir uygulamadır.

Kodu okuduğumda en çok üzüldüğüm şeylerden biri bu çünkü sonunda olan şey, okuyucuyu, tam olarak ne olduğunu anlamak için ipuçları için kodun diğer bölümlerini aramaya zorluyorsunuz ve bu, siz yaptığınızda baş ağrısı olabilir. ihtiyaç anlamak için, sonrasını anlayabilmek için.

function createSignature({ sk, message, pk }: any) {
  
}

Şimdi, bunu yaparken ve bir gün çağırırken kodunuzu yorumlamak istemiyorum:


function createSignature({ sk, message, pk }: any) {
  
}

Bu sadece belirsiz değil, bilmiyoruz nerede mesaj geliyor ya ne bu. Bu bir dize mi? Bir dizi dizi mi? bu mu gereklidir? Bu, e-postanızda alacağınız gibi gerçek bir mesaj mı? Başka bir şey olarak adlandırmak doğru mu? Bunun gerçek anlamı nedir?

Herkese bir iyilik yapın ve bir takım oyuncusu olun:


function createSignature({
  sk,
  message,
  pk,
}: {
  sk: string, 
  message: string,
  pk: string, 
}) {
  
}

5. İşlevlerinizi olumlu bir şekilde adlandırın

İzlenecek iyi bir uygulama, işlevlerinizi, hayattaki iyi şeyleri düşündüğümüzde zihninizin zaten alışık olduğu şeye benzeyecek şekilde adlandırmaktır.

Örneğin, bir bardak su düşündüğümüzde, bardağın yarısının dolu olması mı yoksa bardağın yarısının boş olması mı daha olumludur?

Her ikisi de aynı anlama gelse de, ikincisi, bardağın yarısı boşsa, yakında yeniden doldurmayı düşünmemiz gerektiğine dair olumsuz bir fikre sahiptir. Artık suyumuz kaldı mı? Olmazsa bütün gün dayanabilir miyim?

Şimdi bardağın yarısı dolu dersek, “neredeyse oradayız” şeklinde olumlu bir algı vardır.

Şimdi kodda fonksiyon isimlendirmeye geçelim. DOM düğümleriyle çalışıyorsak ve öğeleri gizleme veya gösterme işlevi yapıyorsak, bir girdi öğesinin kullanılabilir olup olmadığını kontrol eden bir işlevi nasıl adlandırırsınız?

function isEnabled(element) {
  return element.disabled === false
}

function isDisabled(element) {
  return element.disabled === true
}

Hangisini kullanmayı tercih edersin? Hiçbiri yanlış değil, ikisi de aynı şeyi sorunsuz bir şekilde gerçekleştiren işlevlerdir, yalnızca farklı adlandırılmışlardır.

Yani büyük anlaşma nedir?

Koşullu ifadeler yazdığımız veya bir şeyin başarılı olup olmadığını kontrol ettiğimiz tüm zamanları düşünürsek, çoğu zaman almaya alışırız. true Başarılı girişimler için ve false kötü denemeler için

Bu o kadar sık ​​olur ki, kodu yazarken veya okurken koşullu ifadeleri hızlıca gözden geçirebilir ve işlevin geri geldiğini görerek beklenen şekilde davrandığını varsaydığımız senaryolardan kurtulabiliriz. true her şey yolunda görünüyorsa.

Ama bir düşün. eğer takılıp kalırsak isEnabled “etkin” kelimesinin arkasındaki diğer anlamlar için endişelenmemize gerek kalmazdı. Eğer isEnabled true döner, bu gerçekten basittir ve eğer öyleyse eminiz olumsuzluk etkin o zaman düz yukarı anlamına gelir engelli veya false.

eğer takılıp kalırsak isDisabled bunu hatırlamalıyız true dır-dir olumsuzluk bu fonksiyondan olumlu bir sonuç. Bu zaten alışkın olduğumuz şeye aykırı! Ve bu nedenle, kodunuzdaki hata riskini artıran davranışı yanlış anlamak daha kolaydır.

İşte başka bir senaryo. Bir YAML dizesinden değerleri ayrıştırıyorsak, bazen (görünüşte) bir boole değeriyle karşılaşırız. true olarak yazılır "true" veya false olarak "false".

function isBooleanTrue(value) {
  return value === 'true' || value === true
}

function isBooleanFalse(value) {
  return value === 'false' || value === false
}

YAML sözdizimindeki bu örneği düşünün:

- components:
    - type: button
      hidden: 'false'
      style:
        border: 1px solid red

Bu, JSON’a şu şekilde ayrıştırılır:

[
  {
    "components": [
      {
        "hidden": "false",
        "type": "button",
        "style": {
          "border": "1px solid red"
        }
      }
    ]
  }
]

Bir öğenin gizlenip gizlenmediğini kontrol edeceksek, seçebileceğimiz iki seçeneğimiz var: isBooleanTrue ve isBooleanFalse.

Seçersek bunun nasıl göründüğünü görelim isBooleanFalse:

import parsedComponents from './components'

const components = parsedComponents.map((parsedComponent) => {
  const node = document.createElement(parsedComponent.type)

  for (const [styleKey, styleValue] of component) {
    node.style[styleKey] = styleValue
  }

  return node
})

function toggle(node) {
  
  if (isBooleanFalse(node.hidden)) {
    node.style.visibility = 'hidden'
  } else {
    node.style.visibility = 'visible'
  }
}

Bu işlevi yazarken bile bu anlambilimi biraz kafa karıştırıcı buluyorum. Her ne kadar davranış neyi başarsa da toggle Bu karışıklık, kodumuzun basit, okunabilir ve bakımı yapılabilir olması gerektiği konusundaki genel fikri desteklemektedir, bu nedenle işlevlerinizi adlandırmak çok önemlidir.

Çözüm

Ve bu yazının sonu burada bitiyor! Bunu değerli bulduğunuzu ve gelecekte daha fazlasını aradığınızı fark ettim!

İlgili Makaleler

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Başa dön tuşu