Как читать / понимать вложенные троичные значения в объекте json - PullRequest
1 голос
/ 14 июля 2020

Я пытаюсь расшифровать чужой код и не могу понять этот json объект с вложенными троичными значениями для каждого ключа. Пожалуйста, помогите мне понять / прочитать этот код:

ВОПРОС: Как вы это читаете (какая часть if / else назначается, когда и как?)

let permissions = {
    view: currentRole ? Array.isArray(currentRole.view) ? 
      currentRole.view.includes(title) : false : false,
    create: currentRole ? Array.isArray(currentRole.create) ? 
      currentRole.create.includes(title) : false : false,
    edit: currentRole ? Array.isArray(currentRole.edit) ? 
      currentRole.edit.includes(title) : false : false,
    all: currentRole ? Array.isArray(currentRole.all) ? 
      currentRole.all.includes(title) : false : false,
  }

Вот как currentRole определено

const UserContext = createContext({
  authenticated: false, profile: null
});
const [userState, setUserState] = useContext(UserContext);
const currentRole = userState.currentRole;

Пожалуйста, помогите мне понять, как читать часть if / else пары json ключ: значение.

спасибо

Ответы [ 6 ]

1 голос
/ 14 июля 2020

Для одного из вложенных тернарных выражений

currentRole ? Array.isArray(currentRole.view) ? 
  currentRole.view.includes(title) : false : false

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

currentRole
  ? Array.isArray(currentRole.view)
    ? currentRole.view.includes(title)
    : false
  : false;

Теперь его легче увидеть по индексу глубина какие значения go с каким тернарным оператором.

Эквивалентный фрагмент с использованием блоков if-else будет

if (currentRole) {
  if (Array.isArray(currentRole.view)) {
    return currentRole.view.includes(title);
  } else {
    return false;
  }
} else {
  return false
}

Это избыточно, хотя две ветви logi c возвращают одно и то же значение, можно упростить до

if (currentRole && Array.isArray(currentRole.view)) {
  return currentRole.view.includes(title);
} else {
  return false
}

или

currentRole && Array.isArray(currentRole.view)
  ? currentRole.view.includes(title)
  : false;

или даже более просто (кредит на @ cars10m!), который полностью удаляет тернарные операторы

currentRole &&
  Array.isArray(currentRole.view) &&
  currentRole.view.includes(title);

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

1 голос
/ 14 июля 2020

Я полагаю, вы понимаете, что такое тернарный оператор. если нет, посмотрите https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator.

Давайте разберем часть разрешений.

let permissions = {
    view: currentRole ? Array.isArray(currentRole.view) ? 
      currentRole.view.includes(title) : false : false,
    create: currentRole ? Array.isArray(currentRole.create) ? 
      currentRole.create.includes(title) : false : false,
    edit: currentRole ? Array.isArray(currentRole.edit) ? 
      currentRole.edit.includes(title) : false : false,
    all: currentRole ? Array.isArray(currentRole.all) ? 
      currentRole.all.includes(title) : false : false,
  }

и сосредоточимся на

const view = currentRole ? Array.isArray(currentRole.view) ? 
      currentRole.view.includes(title) : false : false;

где мы можем думать об этом как о

const view = currentRole ? Array.isArray(currentRole.view) ? 
      (currentRole.view.includes(title) : false : false);

т.е. если currentRole оценивается как истина, тогда

const view = Array.isArray(currentRole.view);

в противном случае

const view = currentRole.view.includes(title) : false : false;

Не уверен, что это очищает ваш вопрос. Надеюсь, это поможет.

0 голосов
/ 14 июля 2020

Похоже, что автор кода, предназначенного для view, create, edit и all, всегда должен быть ложным, если только currentRole.view, currentRole.create, et c. были определены как истинные в базе данных, возможно. Но иногда им нужно было сделать исключение для тестирования определенного titles. И когда им нужно было протестировать title, они добавляли его в массив и меняли первый оператор перед двоеточием на true . Это позволило бы им протестировать определенный c заголовок так, как он будет выглядеть, когда его можно будет редактировать ... возможно, без входа в систему. У них все это как ложные, поэтому для этого logi c нет никаких причин, кроме как для тестирования отдельных заголовков, не заставляя всю систему делать все доступным для редактирования.

Это похоже на производственный код, на котором тестируется. Сохранение всех троичных значений как false - это механизм безопасности на всякий случай. TL; DR нет причин для всех этих дополнительных лог c, кроме как для проверки определенного title.

0 голосов
/ 14 июля 2020

Начнем с простого тернарного оператора. Например,

a == b ? console.log(a) : console.log(b);

Здесь, если условие a == b истинно, то выполняется первый оператор console.log (a) В противном случае выполняется второй оператор console.log (b).

Правило большого пальца: всегда начинайте читать тернарный оператор с LHS на RHS.

Начнем с вашего кода.

let permissions = {
    view: currentRole ? Array.isArray(currentRole.view) ? 
      currentRole.view.includes(title) : false : false,
    create: currentRole ? Array.isArray(currentRole.create) ? 
      currentRole.create.includes(title) : false : false,
    edit: currentRole ? Array.isArray(currentRole.edit) ? 
      currentRole.edit.includes(title) : false : false,
    all: currentRole ? Array.isArray(currentRole.all) ? 
      currentRole.all.includes(title) : false : false,
  }

Давайте прочитаем ключ просмотра из объекта разрешений

view: currentRole ? Array.isArray(currentRole.view) ? 
      currentRole.view.includes(title) : false : false

Давайте экспортируем этот тернарный оператор:

  1. условие: перед вопросительным знаком (?). currentRole - это условие в вашем случае.

  2. Первое утверждение: после первого вопросительного знака (?) И перед последним двоеточием (:)

    Array.isArray(currentRole.view) ? currentRole.view.includes(title) : false

    Это первая инструкция в вашем случае.

  3. Вторая инструкция: после последнего двоеточия (:) false - это вторая инструкция в вашем случае

Теперь давайте подумаем только о простом тернарном операторе.

Если условие истинно, то будет выполняться первый оператор. В противном случае будет выполнен второй оператор. В вашем случае

  1. Предположим, что currentRole истинно, тогда будет выполнено

    Первое выражение Array.isArray(currentRole.view) ?currentRole.view.includes(title) : false. Теперь снова рассматривайте это первое утверждение как тернарный оператор! Независимо от того, какое значение, возвращаемое этим оператором поворота, будет значением view key

  2. Предположим, что currentRole ложно, тогда будет выполнено второе утверждение false. Таким образом, view key значение будет false

0 голосов
/ 14 июля 2020

Тернарные операции:

Рассмотрим пример:

condition ? trueResult : falseResult

Эквивалентно:

if(condition)
{
return trueResult
}
else{
return falseResult
}

Другой

condition1? return1
:conditions? return2
:conditions?return3 

аналогичен

if(condition1){

return return1

}elseif(condition2){

return return2

}elseif(condition3){

return return3

}

Другой

condition1 ? condition2 ? return1:return2:return3

эквивалентен:

if(condition1){

if(condition2){

return return1

}else{

return return2

}

}else{

return return3

}

Аналогично в вашем состоянии

 view: currentRole ? Array.isArray(currentRole.view) ? 
      currentRole.view.includes(title) : false : false,

Является эквивалент

if(currentRole){

if(Array.isArray(currentRole.view){

return currentRole.view.includes(title)

}else{

return false

}}else{

return false

}
0 голосов
/ 14 июля 2020

Это не дополнительное объяснение - @Drew Reese уже проделал большую работу над этим - но это еще один короткий способ создания JSON:

let currentRole={edit:['game'],all:['comments']},
    title='game';

let res="view,create,edit,all".split(',').reduce((a,c)=> 
   (a[c] = currentRole            
        && Array.isArray(currentRole[c])            
        && currentRole[c].includes(title),a), {});

console.log(res);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...