Jadvalni Javascript ES6 da funktsiya parametrlari sifatida qanday o'tkaziladi?

Qanday qilib siz Javascriptdagi funktsional mustaqil o'zgarish sifatida kalit so'zi olasiz?

Men buni Redux kutubxonasi bilan qilishni xohlayman:

const agendaPointsReducer = function (state = initialState, action) {
  return Object.assign({}, state, switch (action.type) {
    case OPEN_AGENDA_POINT: {
      state.modal_is_open = true,
      state.point_id = action.id
    }
    case CLOSE_AGENDA_POINT: {
      state.modal_is_open = false
    }
  })
}

Lekin men kutilmagan xatolik yuz berdi. Buni Coffeescript da mavjud bo'lishi mumkinligini bilaman, Javascript es6 da buni qilishning usullari bormi?

0
Funktsiya argumenti sifatida yon ta'sirdan o'tish nimani anglatadi? switch so'zlari ifodalar bo'lsa ham, misoldagi kod undefined
qo'shib qo'ydi muallif Balázs Édes, manba
Siz kalit so'zini bera olmaysiz. Buni bir funktsiyani o'rashingiz kerak. Biroq, Object.assign() siz uni ko'chirishga imkon beradigan xususiyatlarga ega bo'lgan ob'ektni topshirishingizni kutadi. Shunday qilib, siz u yerda ob'ektni topshirishingiz kerak.
qo'shib qo'ydi muallif jfriend00, manba
Sizning savolingiz hozir javob berdimi? Agar shunday bo'lsa, iltimos, eng yaxshi javobni tanlang va uning yonida yashil tasdiq belgisini bosing.
qo'shib qo'ydi muallif jfriend00, manba
Nima demoqchisiz? Qanday?
qo'shib qo'ydi muallif Aurimas, manba

6 javoblar

Buning bir sababi shundaki, uni quyidagi funktsiyaga kiritish kerak:

const agendaPointsReducer = function (state = initialState, action) {
  return Object.assign({}, state, (() => {
    switch (action.type) {
      case OPEN_AGENDA_POINT: {
        state.modal_is_open = true,
        state.point_id = action.id
      }
      case CLOSE_AGENDA_POINT: {
        state.modal_is_open = false
      }
    }
  })())
}
3
qo'shib qo'ydi
Uhhh, Object.assign() xususiyatlarga ega bo'lgan ob'ektni kutmoqda va xususiyatlar nusxalanadi. Object.assign() deyishdan oldin kerakli ob'ektni yaratib, keyin u ob'ektni atayin. Bu kodni (hatto ishlayotgan bo'lsa) kuzatish juda qiyin.
qo'shib qo'ydi muallif jfriend00, manba
Men buni qanday qilib to'g'ri yo'l bilan amalga oshirish mumkinligini hali ham ko'rmayapman. Yomon ta'sir ko'rsatadigan holat ob'ektini o'zgartirasiz. Object.assign() kodini undefined dan faqatgina noto'g'ri bo'lgan uchinchi dalil sifatida o'tasiz. Bu yon ta'sir tufayli tasodifan ishlay olishi mumkin, lekin bu, albatta, narsalarni qilishning to'g'ri usuli emas.
qo'shib qo'ydi muallif jfriend00, manba
Har bir ob'ektdan oldin return iborasi kerak deb o'ylayman!
qo'shib qo'ydi muallif ibrahim mahrir, manba
Bundan tashqari, anonim funksiya ichida allaqachon belgilangan status parametrini o'tkazishning hojati yo'q!
qo'shib qo'ydi muallif ibrahim mahrir, manba
Qiziqarli ko'rinadi, buni sinab ko'rasiz
qo'shib qo'ydi muallif Aurimas, manba
Kimdir to'g'ri kod va to'g'ri chiziq bilan ishlaydigan namuna ko'rsatishi mumkinmi? @ jfriend00
qo'shib qo'ydi muallif Aurimas, manba
Hech qaysi break yoki return berilgan asl kodni ishlatgan.
qo'shib qo'ydi muallif daniel_franz, manba
Siz haqsiz. Ushbu qismni o'zgartiradi
qo'shib qo'ydi muallif daniel_franz, manba
Siz haqsiz. Menimcha, u ishlashi kerak, ammo bu juda qiyin.
qo'shib qo'ydi muallif daniel_franz, manba

switch statements are not expressions in Javascript. In Coffeescript, everything is an expression (a la Ruby). Due to this, there is not a way to do this. Further, in the example you have just shown, there is no reason to, as your switch statement is just modifying the state variable which is already being passed.

2
qo'shib qo'ydi

Shunday qilib, Object.assign() xususiyati ob'ektni maqsad ob'ektga uzatadigan narsalardan ko'chiradi. Shunday qilib, uni o'tkazishingiz kerak bo'lgan narsalar nusxa olish xususiyatiga ega bo'lgan narsalardir.

Agar siz nima qilmoqchi bo'lsangiz, bu sizning harakatingizni amalga oshirishga asoslangan (bu nima qilmoqchi ekanligimni taxmin qiladigan) switch bayonotining joriy bajarilishiga asoslangan xususiyatga ega bo'lgan ob'ektni yaratishdir. Object.assign() ni chaqirmasdan oldin manba obyektini ishga tushiring va unga shu ob'ektni topshiring.

Bu erda ko'rsatilgan usulni bajarish ob'ektga kiritilgan ob'ektni o'zgartiradigan har qanday yon ta'sirlardan qochadi (shuning uchun biz kalitlarni status ob'ektiga emas, balki mahalliy ob'ektga switch funksiyasida o'rnatamiz):

const agendaPointsReducer = function (state = initialState, action) {
    let srcObj = {};
    switch (action.type) {
        case OPEN_AGENDA_POINT:
            srcObj.modal_is_open = true;
            srcObj.point_id = action.id;
            break;
        case CLOSE_AGENDA_POINT:
            srcObj.modal_is_open = false;
            break;
    }

    return Object.assign({}, state, srcObj);
}
1
qo'shib qo'ydi

daniel_franz va jfriend00 - eng yaxshi va eng sodda echimlar. Ammo muqobillar haqida o'ylash hali ham qiziqarli :)

Men switch mantiqini Map da saqlashga harakat qilib, qiziqarli tajriba o'tkazdim. Ehtimol, bir necha kamchiliklar mavjud (birinchidan, break ni qoldirib, vaziyatni zanjirlay olmaysiz) va u juda murakkab ishlarni amalga oshiradi, shuning uchun biz uni faqatgina qidiruv "haqiqiy loyihada shunday qilaman" degani emas, balki ...

Yondashuv:

  • Har case uchun Map yaratish
  • Har bir kirish case kalitiga ega
  • Har bir kirishda istalgan natijani
  • sifatida qaytaradigan funktsiyasi mavjud
  • Belgilanmagan holatlar uchun getItem kodi null funksiyasini qaytaradi va biz ham funktsiyani bajaramiz

Kod:

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="true"> <div class="snippet-code">

const apply = f => typeof f === "function" ? f() : null;
const Switch = (input, ...entries) => apply(new Map(entries).get(input));

const types = {
  INCREMENT: "INCREMENT",
  DECREMENT: "DECREMENT",
  SQUARE: "SQUARE"
};


const myNumberReducer = function(state = { myNumber: 0 }, action = {}) {
  return Object.assign({}, state, Switch(action.type,
    [ types.INCREMENT,() => ({ myNumber: state.myNumber + 1 }) ],
    [ types.DECREMENT,() => ({ myNumber: state.myNumber - 1 }) ],
    [ types.SQUARE,   () => ({ myNumber: state.myNumber * state.myNumber }) ]
  ));
}


let lastState = myNumberReducer();
console.log(lastState);//myNumber: 0

lastState = myNumberReducer(lastState, { type: types.INCREMENT });
console.log(lastState);//myNumber: 1

lastState = myNumberReducer(lastState, { type: types.INCREMENT });
lastState = myNumberReducer(lastState, { type: types.SQUARE });
console.log(lastState);//myNumber: 4
</div> </div>

1
qo'shib qo'ydi

Sizning savolingizga beriladigan javoblarga qo'shimcha ravishda sizga yana umumiy javob berishni xohlayman.

Funktsiyaga switch iborasini kiritish uchun siz uni ifodalashga aylantirishingiz kerak. Bunga erishishning ikki xil yo'li bor.

Funktsiyada switch ni o'rang

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

const apply = f => x => f(x);

const enumerate = apply(x => {
  switch (x.constructor) {
    case Number: {
      return inc(x);
    }

    case String: {
      return succ(x);
    }

    default: throw TypeError();
  }
});

const inc = x => x + 1;

const succ = x => String.fromCharCode(x.charCodeAt(0) + 1);

console.log("enum 1:", enumerate(1));//2

console.log("enum a:", enumerate("a"));//"b"
</div> </div>

With this approach I use apply as a little auxiliary function. It makes the calling code more readable, e.g. Object.assign({}, state, apply(x => {/* switch statement */}) (action.type))

Funktsiya sifatida switch ni ishlating

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

const caseOf = (...pairs) => x => {
  let g;

  pairs.some(([guard, f], i) => guard(x) 
   ? (g = f, true)
   : false);

  return g(x);
}

const inc = x => x + 1;

const succ = x => String.fromCharCode(x.charCodeAt(0) + 1);

const enumerate = caseOf(
  [x => x.constructor === Number, x => x + 1],
  [x => x.constructor === String, x => String.fromCharCode(x.charCodeAt(0) + 1)]
);

console.log("enum 1:", enumerate(1));

console.log("enum a:", enumerate("a"));
</div> </div>

caseOf is a normal function, a higher order function to be more precise. You can apply it wherever an expression is allowed.

Tahribotlarni belgilash

Tahribotlarni belgilash is an non-obvious advantage that both approaches have over normal switch statements. You can apply Tahribotlarni belgilash without additional variables:

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

const apply = f => x => f(x);

const sqr = x => x * x

const xs = [2],
 ys = [];

console.log(
  sqr(apply(([x]) => {//<= Tahribotlarni belgilash
    switch (x) {
      case undefined: return 0;
      default: return x;
    }
  }) (xs))
);

console.log(
  sqr(apply(([x]) => {//<= Tahribotlarni belgilash
    switch (x) {
      case undefined: return 0;
      default: return x;
    }
  }) (ys))
);
</div> </div>

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

const caseOf = (...pairs) => x => {
  let g;

  pairs.some(([guard, f], i) => guard(x) 
   ? (g = f, true)
   : false);

  return g(x);
}

const sqr = x => x * x;

const isAssigned = x => x !== undefined && x !== null;

const always = x => _ => x;

const xs = [5],
 ys = [];
 
console.log(
  caseOf(
    [([x]) => isAssigned(x), sqr],//<= Tahribotlarni belgilash
    [always(true), always(0)]//default case
  ) (xs)
);

console.log(
  caseOf(
    [([x]) => isAssigned(x), sqr],//<= Tahribotlarni belgilash
    [always(true), always(0)]//default case
  ) (ys)
);
</div> </div>

Umid qilamanki yordam beradi.

1
qo'shib qo'ydi

Men, albatta, nima qilishni xohlasangiz, shunga o'xshash narsa:

const agendaPointsReducer = function (state = initialState, action) {
  switch (action.type) {
    case OPEN_AGENDA_POINT: {
      return {
        ...state,
        modal_is_open: true,
        point_id: action.id
      };
    }
    case CLOSE_AGENDA_POINT: {
      return {
        ...state,
        modal_is_open: false,
      };
    }
  }
}
1
qo'shib qo'ydi
Bu ishlaydi, lekin ba'zi bir sytax xatoliklarni tuzatgandan keyin.
qo'shib qo'ydi muallif Aurimas, manba
ReactJS & ReactNative Uzbekistan
ReactJS & ReactNative Uzbekistan
81 ishtirokchilar

Guruh ReactJS va ReactNative bo'yicha muloqot qilish uchun ochilgan. Sizni qiziqtirsa: @nodejs_uz @react_uz @angular_uz @ngTashkent @yiiframework_uz @js_uzb @typescript_uzb @vuejs_uz @ngTashkent @laravel_uz @uzdevgroup Ish o'rinlari @UzDev_jobs