Советы по улучшению счастья в JS

внешний интерфейс JavaScript Element
Советы по улучшению счастья в JS

В этой статье в основном представлены некоторые советы, используемые в JS, которые могут улучшить качество ежедневного кодирования, и будут время от времени обновляться~

Заинтересованные студенты могут добавить группу WeChat в конце статьи для совместного обсуждения~

1. Приведение типов

1.1 привести строку к числу

Можно использовать*1преобразовать в число (фактически вызывая.valueOfметод) затем используйтеNumber.isNaNопределить, является лиNaNили используйтеa !== aопределить, является лиNaN,потому чтоNaN !== NaN

'32' * 1            // 32
'ds' * 1            // NaN
null * 1            // 0
undefined * 1    // NaN
1  * { valueOf: ()=>'3' }        // 3

Обычно используется:также можно использовать+для преобразования строк в числа

+ '123'            // 123
+ 'ds'               // NaN
+ ''                    // 0
+ null              // 0
+ undefined    // NaN
+ { valueOf: ()=>'3' }    // 3

1.2 объект принудительно преобразуется в строку

можно использовать字符串+Objectспособ преобразования объекта в строку (на самом деле вызов.toString()метод)

'the Math object:' + Math                // "the Math object:[object Math]"
'the JSON object:' + JSON              // "the JSON object:[object JSON]"

Конечно, вы также можете переопределить объектtoStringа такжеvalueOfметод для настройки преобразования типов объектов:

2  * { valueOf: ()=>'3' }                // 6
'J' + { toString: ()=>'S' }                // "JS"

«Эффективный JavaScript» P11: когда+Используется при объединении строк, когда объект имеет обаtoStringметод имеетvalueOfметод, JS использует вслепуюvalueOfметод разрешения этой двусмысленности. объект черезvalueOfметод принуждения к числу, черезtoStringСпособ литой строки

'' + {toString:()=>'S',valueOf:()=>'J'}                // J

1.3 Используйте Boolean для фильтрации всех ложных значений в массиве

Мы знаем, что в JS есть несколько поддельных значений:false,null,0,"",undefined,NaN, как быстро отфильтровать ложные значения в массиве, вы можете использовать логический конструктор для выполнения преобразования

const compact = arr => arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34])             // [ 1, 2, 3, 'a', 's', 34 ]

1.4 Двойной битовый оператор ~~

Вместо положительных чисел можно использовать двойной битовый оператор.Math.floor( ), вместо отрицательногоMath.ceil( ). Преимущество побитового оператора двойного отрицания состоит в том, что он выполняет ту же операцию быстрее.

Math.floor(4.9) === 4      //true
// 简写为:
~~4.9 === 4      //true

Обратите внимание, однако, что для положительных чисел~~Результат операции иMath.floor( )Результат операции тот же, а для отрицательных чисел такой же, какMath.ceil( )Результат операции тот же:

~~4.5                // 4
Math.floor(4.5)      // 4
Math.ceil(4.5)       // 5

~~-4.5        		// -4
Math.floor(-4.5)     // -5
Math.ceil(-4.5)      // -4

1.5 Операторы короткого замыкания

Мы знаем, что логично и&&И логическое ИЛИ||Это оператор короткого замыкания.Оператор короткого замыкания означает, что первый удовлетворяет требованиям в операции слева направо, а второй больше не выполняется; Это можно понять как:

  • &&Чтобы принять ложную операцию, судите слева направо, если встречается ложное значение, она вернет ложное значение и не будет выполняться в будущем, иначе она вернет последнее истинное значение.
  • ||Чтобы принять истинную операцию, судите слева направо по очереди.Если встречается истинное значение, возвращается истинное значение, и оно не будет выполняться в будущем, иначе возвращается последнее ложное значение.
let param1 = expr1 && expr2
let param2 = expr1 || expr2
оператор Пример иллюстрировать
&& expr1&&expr2 Возвращает expr1, если expr1 можно преобразовать в false, в противном случае возвращает expr2.Поэтому при использовании в логическом контексте возвращает true, если обе операции приводят к true, в противном случае возвращает false.
|| expr1||expr2 Если expr1 можно преобразовать в true, вернуть expr1, в противном случае вернуть expr2. Следовательно, при использовании в логической среде (в условной оценке if), пока один из двух результатов операции истинен, вернуть true; оба результата операции are Возвращает false, если false.
! !expr Возвращает false, если одно выражение может быть преобразовано в true, в противном случае возвращает true.

Поэтому с его помощью можно делать много интересных вещей, например, присваивать начальные значения переменным:

let variable1
let variable2 = variable1  || 'foo'

Если переменная1 является истинным значением, оно будет возвращено напрямую, и последующее короткое замыкание не будет возвращено.Если это ложное значение, оно вернет следующееfoo.

Его также можно использовать для вынесения простых суждений вместо длинных рассуждений.ifЗаявление:

let variable = param && param.prop

еслиparamвернуть, если правдаparam.propсвойство, в противном случае возвратparamэто ложное значение, которое в некоторых местах мешаетparamдляundefinedКогда он также принимает свои свойства, чтобы вызвать ошибку.

1.6 Округление| 0

на номер| 0Это может быть округлено, и то же самое относится к негативным числам.num | 0

1.3 | 0         // 1
-1.9 | 0        // -1

1.7 Оценка нечетных и четных чисел& 1

на номер& 1Вы можете судить о нечетных и четных числах, и то же самое относится к отрицательным числам.num & 1

const num=3;
!!(num & 1)                    // true
!!(num % 2)                    // true

2. Функция

2.1 Значение функции по умолчанию

func = (l, m = 3, n = 4 ) => (l * m * n);
func(2)             //output: 24

Обратите внимание, что входящие параметрыundefinedИли, если они не переданы, будут использоваться параметры по умолчанию, но переданыnullОн по-прежнему перезаписывает параметры по умолчанию.

2.2 Обязательные параметры

По умолчанию, если вы не передадите значение параметру функции, JS установит для параметра функции значениеundefined. Другие языки будут выдавать предупреждения или ошибки. Чтобы выполнить назначение параметров, вы можете использоватьifоператор выдает неопределенную ошибку или может быть использован强制参数.

mandatory = ( ) => {
  throw new Error('Missing parameter!');
}
foo = (bar = mandatory( )) => {     // 这里如果不传入参数,就会执行manadatory函数报出错误
  return bar;
}

2.3 Неявное возвращаемое значение

Возвращаемое значение - это ключевое слово, которое мы обычно используем для возврата окончательного результата функции. Стрелка функционирует только с одним утверждением, которое может неявно возвращать результат (функция должна опускать фигурные скобки{ }, так что ключевое слово return опущено).

Чтобы вернуть многострочный оператор (например, литерал объекта), вам нужно использовать( )вместо{ }чтобы обернуть тело функции. Это гарантирует, что код оценивается как один оператор.

function calcCircumference(diameter) {
  return Math.PI * diameter
}
// 简写为:
calcCircumference = diameter => (
  Math.PI * diameter;
)

2.4 Функции ленивой загрузки

В определенном сценарии в нашей функции есть оператор суждения.Эта основа суждения обычно не меняется в течение работы всего проекта.Поэтому ветвь суждения будет запускать только конкретную ветвь во время работы всего проекта, поэтому можно рассмотреть функцию ленивой загрузки.

function foo(){
    if(a !== b){
        console.log('aaa')
    }else{
        console.log('bbb')
    }
}
 
// 优化后
function foo(){
    if(a != b){
        foo = function(){
            console.log('aaa')
        }
    }else{
        foo = function(){
            console.log('bbb')
        }
    }
    return foo();
}

Тогда этот метод будет перезаписан после первого запуска, и решение не будет выполнено при следующем запуске. Суд, конечно, сейчас один, а если судов много и ветки посложнее, то экономия ресурсов все равно немалая.

2.5 Одноразовые функции

Подобно вышеприведенной функции ленивой загрузки, вы можете перезаписать текущую функцию в теле функции, затем вы можете создать одноразовую функцию.Код перед переназначением эквивалентен запуску только один раз, что подходит для запуска некоторых функций, которые нужны только выполняется один раз. код инициализации

var sca = function() {
    console.log('msg')
    sca = function() {
        console.log('foo')
    }
}
sca()        // msg
sca()        // foo
sca()        // foo

3. Строка

3.1 Временная последовательность сравнения строк

Вы можете использовать строки для сравнения в хронологическом порядке:

var a = "2014-08-08";
var b = "2014-09-09";
 
console.log(a>b, a<b); // false true
console.log("21:00"<"09:10");  // false
console.log("21:00"<"9:10");   // true   时间形式注意补0

Потому что размер сравнения строк соответствует каждому символу строки слева направоcharCodeПриходите, но так обратите особое внимание на форму времени и добавьте 0

4. Числа

4.1 Различные базовые обозначения

В ES6 добавлены различные базовые форматы записи, обратите на это внимание при передаче параметров в фоновом режиме.

29            // 10进制
035            // 8进制29      原来的方式
0o35            // 8进制29      ES6的方式
0x1d            // 16进制29
0b11101            // 2进制29

4.2 Десятичные числа с точностью до указанного количества цифр

Округляет число до указанного количества знаков после запятой. использоватьMath.round()и литералы шаблонов округляют число до указанного количества знаков после запятой. Опустить второй параметрdecimals, число будет округлено до целого числа.

const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
round(1.345, 2)                 // 1.35
round(1.345, 1)                 // 1.3

4.3 Операция прибавления 0 к числам

Спасибо пользователю сети @JserWang @vczhan за этот маленький трюк. Иногда, например, при отображении времени иногда необходимо отображать одну цифру как две цифры, в это время необходимо заполнить 0. Вы можете использоватьsliceи струныpadStartметод

const addZero1 = (num, len = 2) => (`0${num}`).slice(-len)
const addZero2 = (num, len = 2) => (`${num}`).padStart( len   , '0')
addZero1(3) // 03
 
addZero2(32,4)  // 0032

5. Массивы

5.1 Метод сокращения реализует как карту, так и фильтр

Предположим, что теперь есть массив, и вы хотите обновить каждый элемент в нем (функция map), а затем отфильтровать часть (функция filter). Если вы сначала используете карту, а затем фильтр, вам нужно дважды перебрать массив. В приведенном ниже коде мы удваиваем значения в последовательности и выбираем те числа, которые больше 50.

const numbers = [10, 20, 30, 40];
const doubledOver50 = numbers.reduce((finalList, num) => {
  num = num * 2;
  if (num > 50) {
    finalList.push(num);
  }
  return finalList;
}, []);
doubledOver50;            // [60, 80]

5.2 Подсчитайте количество одинаковых элементов в массиве

Много раз вам нужно подсчитать количество повторяющихся элементов в массиве и представить его в виде объекта. Затем вы можете использовать метод сокращения для обработки этого массива.

Следующий код будет подсчитывать количество автомобилей каждого типа, а затем представлять общее количество в виде объекта.

var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];
var carsObj = cars.reduce(function (obj, name) {
  obj[name] = obj[name] ? ++obj[name] : 1;
  return obj;
}, {});
carsObj; // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }

5.3 Использование деструктуризации для обмена значениями параметров

Иногда вы помещаете в массив несколько значений, возвращаемых функцией. Мы можем использовать деструктуризацию массива, чтобы получить каждое из этих значений.

let param1 = 1;
let param2 = 2;
[param1, param2] = [param2, param1];
console.log(param1) // 2
console.log(param2) // 1

Конечно, у нас есть много других способов поменять местами значения:

var temp = a; a = b; b = temp            
b = [a, a = b][0]                     
a = a + b; b = a - b; a = a - b        

5.4 Получение нескольких результатов, возвращаемых функцией

В приведенном ниже коде мы извлекаем сообщение из /post, а затем получаем соответствующие комментарии из /comments. Поскольку мы используем async/await, функция помещает возвращаемое значение в массив. И после того, как мы используем деструктуризацию массива, мы можем напрямую присвоить возвращаемое значение соответствующей переменной.

async function getFullPost(){
  return await Promise.all([
     fetch('/post'),
     fetch('/comments')
  ]);
}
const [post, comments] = getFullPost();

5.5 Мозаика массива до указанной глубины

Используйте рекурсию для каждого уровня глубиныdepthУменьшить на 1 . использоватьArray.reduce()а такжеArray.concat()для объединения элементов или массивов. В принципе,depthРавно 1, чтобы остановить рекурсию. Опустите второй параметр,depthВы можете размещать мозаику только до глубины 1 (однослойная мозаика).

const flatten = (arr, depth = 1) =>
  depth != 1
    ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
    : arr.reduce((a, v) => a.concat(v), []);
flatten([1, [2], 3, 4]);                             // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2);           // [1, 2, 3, [4, 5], 6, 7, 8]

5.6 Объектная деструктуризация массивов

Массивы также могут быть уничтожены как объекты, которые могут легко получить n-е значение массива.

const csvFileLine = '1997,John Doe,US,john@doe.com,New York';
const { 2: country, 4: state } = csvFileLine.split(',');
 
country            // US
state            // New Yourk

6. Объекты

6.1 Используйте деструктурирование для удаления ненужных свойств

Иногда вы не хотите сохранять определенные свойства объекта, возможно, потому, что они содержат конфиденциальную информацию или слишком велики. Вы можете перечислить весь объект и удалить их, но на практике вы можете просто присвоить бесполезные свойства переменным и передать полезные части, которые хотите сохранить, в качестве оставшихся параметров.

В приведенном ниже коде мы хотим удалить параметры _internal и tooBig. Мы можем присвоить их внутренним переменным и переменным tooBig, а затем сохранить остальные свойства в cleanObject для последующего использования.

let {_internal, tooBig, ...cleanObject} = {el1: '1', _internal:"secret", tooBig:{}, el2: '2', el3: '3'};
 
console.log(cleanObject);                         // {el1: '1', el2: '2', el3: '3'}

6.2 Деструктуризация вложенных объектов в параметрах функции

В приведенном ниже коде двигатель — это объект, вложенный в объект автомобиля. Если нас интересует свойство vin движка, мы можем легко получить его, используя присваивание деструктурирования.

var car = {
  model: 'bmw 2018',
  engine: {
    v6: true,
    turbo: true,
    vin: 12345
  }
}
const modelAndVIN = ({model, engine: {vin}}) => {
  console.log(`model: ${model} vin: ${vin}`);
}
modelAndVIN(car); // => model: bmw 2018  vin: 12345

7. Повторное использование кода

7.1 Object [key]

Хотяfoo.barнаписано какfoo ['bar']это обычная практика, но она образует основу для написания многоразового кода. Многие рамки используют этот метод, такой как элементпроверка формы.

Рассмотрим следующий упрощенный пример функции проверки:

function validate(values) {
  if(!values.first)
    return false;
  if(!values.last)
    return false;
  return true;
}
console.log(validate({first:'Bruce',last:'Wayne'})); // true

Вышеупомянутая функция отлично завершает работу по проверке. Но когда форм много, нужно применять валидацию, а также разные поля и правила. Было бы неплохо, если бы можно было создать общую функцию проверки, которая настраивалась во время выполнения.

// object validation rules
const schema = {
  first: {
    required:true
  },
  last: {
    required:true
  }
}
 
// universal validation function
const validate = (schema, values) => {
  for(field in schema) {
    if(schema[field].required) {
      if(!values[field]) {
        return false;
      }
    }
  }
  return true;
}
console.log(validate(schema, {first:'Bruce'})); // false
console.log(validate(schema, {first:'Bruce',last:'Wayne'})); // true

Теперь, когда у нас есть эта функция проверки, мы можем повторно использовать ее во всех формах без необходимости писать собственную функцию проверки для каждой формы.


  1. Добавьте восторженных пользователей сети @JserWang @vczhan при условииЦифровое дополнение 0 операция
  2. Добавить 3.1, временная последовательность сравнения строк
  3. Спасибо пользователю сети @Pandaaa за напоминание,~~Ведет себя с отрицательными числамиMath.ceil( )такой же

Большинство сообщений в Интернете имеют разную глубину и даже некоторые несоответствия. Следующие статьи являются кратким изложением процесса обучения. Если вы найдете какие-либо ошибки, пожалуйста, оставьте сообщение, чтобы указать ~

Ссылаться на:

  1. Сокращенные приемы, которые нужно знать разработчикам JavaScript
  2. «Эффективный Javascript»
  3. Советы по ES6, которые вы должны знать
  4. Некоторые специальные применения операторов js
  5. Продвинутые навыки JS (краткая версия)
  6. Небольшой разговор о размере сравнения строк в js

Рекомендуемое чтение:Демонстрационный сайт ES6

PS: Всех приглашаю обратить внимание на мой публичный аккаунт [Front End Afternoon Tea], давайте работать вместе~

Кроме того, вы можете присоединиться к группе WeChat «Front-end Afternoon Tea Exchange Group», нажмите и удерживайте, чтобы определить QR-код ниже, чтобы добавить меня в друзья, обратите вниманиеДобавить группу, я заберу тебя в группу~