[訳]JavaScript Mutationの突然変異とPureFunctionの純粋な関数を理解する
6594 ワード
可変性、純関数、副作用、状態可変などの単語はほとんど毎日見られますが、彼らがどのように働いているのか、そして彼らが何なのかはほとんど分かりません.
本論文では,これらのすべてを深く研究して,それらが何であるかを知り,どのようにそれらを利用して,我々のWebアプリケーションの性能を向上させるかを調べる.
Javascript:オリジナルデータタイプと参照データタイプ
私たちはまず、JSがどのように私たちのデータタイプを維持し、訪問するかを知ります.
JSには、元のデータタイプと参照データタイプがあります.元のデータタイプは元のデータタイプではなく値によって参照されます.
元のデータタイプは:
let one = 1
呼び出しスタックにおいて、one
変数は直接値1を指す.Call Stack
#000 one -> | 1 |
#001 | |
#002 | |
#003 | |
もし私たちがこの値を変更すると:let one = 1
one = 3
変数one
のメモリアドレス〹000はもともと1という値を記憶していますが、直接3になります.しかし、このように参照データの種類を書いたら、
let arr = {
one: 1
}
または:let arr = new Object()
arr.one = 1
JSはメモリのヒープにオブジェクトを作成し、対象のメモリアドレスをヒープに保存します.Call Stack Heap
#000 arr -> | #101 | #101 | one: 1 |
#001 | | #102 | |
#002 | | #103 | |
#003 | | #104 | |
arr
がオブジェクトを直接記憶するのではなく、オブジェクトのメモリ位置を指しているのが見える(#101).直接値を保存する元のデータタイプとは異なります.let arr = { one: 1 }
// arr holds the memory location of the object {one: 1}
// `arr` == #101
let one = 1;
// `one` a primitive data type holds the value `1`
// one == 1
arr
の属性を変更すると、次のようになります.arr.one = 2
基本的には、arr
のオブジェクト属性値に対する指向性の変更をプログラムに教えています.C/C++などの言語の指針や引用に詳しいなら、これらは分かりやすくなります.参照データの種類を渡すときは、実際の値ではなく、そのメモリの位置だけを転送します.
function chg(arg) {
//arg points to the memory address of { one: 1 }
arg.one = 99
// This modification will affect { one: 1 } because arg points to its memory address, 101
}
let arr = { one: 1 }
// address of `arr` is `#000`
// `arr` contains `#101`, adrress of object, `{one: 1}` in Heap
log(arr); // { one: 1 }
chg(arr /* #101 */)
// #101 is passed in
log(arr) // { one: 99 }
// The change affected `arr`
arr自身のメモリアドレスは铀000です.arrには住所書が保存されています.この住所は対象を指します.chg関数を呼び出した場合、arg属性oneを修正すると、arr対応の靟101アドレスが指すオブジェクト{one:1}が修正されます.データタイプを引用して保存しているのはメモリアドレスですので、彼の任意の変更はメモリに影響します.
オリジナルのデータタイプが入ってきたら、
function chg(arg) {
arg++
}
let one = 1; // primitive data types holds the actual value of the variable.
log(one) // 1
chg(one /* 1 */)
// the value of `one` is passed in.
log(one) // one is still `1`. No change because primitives only hold the value
元のデータタイプと違って、彼の値はどれぐらいですか?この値を修正したら、そのメモリの対応するこの値を直接修正します.状態突然変異と不可変性
生物学の分野では、DNAとDNAの突然変異を知っています.DNAには4つの基本的な元素があります.それぞれATGCです.これらはコード情報を生成し、人体内にたんぱく質を生成する.
ATATGCATGCGATA
||||||||||||||
TACGAGCTAGGCTA
|
|
v
AProteinase
Information to produce a protein (eg, insulin etc)
上記のDNA鎖は骨構造比のペアに利用できるAPプロテナーゼタンパクを生成するために情報を符号化する.もし私たちがDNAのペアを変えるなら、ペアでも大丈夫です.
ATATGCATGCGATA
||||||||||||||
TACGAGCTAGGCTA
|
v
GTATGCATGCGATA
||||||||||||||
TACGAGCTAGGCTA
DNAは蛋白質のAPプロテナーゼの情報が改竄されているため、異なる蛋白質を生成します.そのため別のタンパク質が生成され、良性であるか、あるいはある場合には毒であるかもしれない.GTATGCATGCGATA
||||||||||||||
TACGAGCTAGGCTA
|
|
V
Now produces _AProtienase
このような変化は
またはDNA
と呼ぶ.突然変異はDNA状態の変化を引き起こす.
JSにとっては、参照データタイプ(配列、オブジェクト)のことをデータ構造と呼びます.これらのデータ構造は私たちのアプリケーションを操作するために情報を保存します.
let state = {
wardens: 900,
animals: 800
}
上の名前の「state」のオブジェクトは、Zooアプリケーションの情報を保存しています.アニメーション属性の値を変更した場合:let state = {
wardens: 900,
animals: 800
}
state.animals = 90
私たちのstateオブジェクトは新しい情報を保存または符号化します.state = {
wardens: 900,
animals: 90
}
これを mutation
と呼びます.私たちのstateは:
state = {
wardens: 900,
animals: 800
}
変更:state = {
wardens: 900,
animals: 90
}
私たちがスタントを保護したい時は、変性しないimmutabilityを使う必要があります.私たちのstateオブジェクトの変化を防ぐために、stateオブジェクトの新しいインスタンスを作成しなければなりません.function bad(state) {
state.prp = 'yes'
return state
}
function good(state) {
let newState = { ...state }
newState.prp = 'yes'
return newState
}
可変性は、私たちのアプリケーションの状態を予測し、アプリケーションの性能速度を向上させ、状態の変化を簡単に追跡することができます.純関数と副作用
純関数は、入力を受け付け、値を返します.その範囲外の任意のデータの関数(副作用)を変更しません.その出力または戻り値は入力/パラメータに依存しなければなりません.純粋な関数は値を返さなければなりません.
純粋な関数は、副作用が発生しない、戻り値は、入ってきたパラメータによって決まります.純粋な関数は値を返さなければなりません.
function impure(arg) {
finalR.s = 90
return arg * finalR.s
}
上記の関数は、その範囲外の状態finalR.s
を修正するため、純粋な関数ではない.function impure(arg) {
let f = finalR.s * arg
}
上の関数も純関数ではありません.外部状態は変更されていませんが、値は返されていません.function impure(arg) {
return finalR.s * 3
}
上記の関数は不純であり、外部状態に影響はないが、出力はfinalR.s * 3
に戻る.入力arg
に依存しない.純粋な関数は値を返すだけでなく、入力にも依存しなければなりません.function pure(arg) {
return arg * 4
}
上の関数が純関数です.どの外部状態にも副作用はなく、入力に応じて出力に戻ります.メリット
個人的には、私が発見した唯一の理解できる利点は
mutation tracking
変異追跡です.いつあなたの状態をレンダリングするかを知ることはとても重要です.多くのJSフレームは良い方法を設計して、いつその状態をレンダリングしますか?しかし、最も重要なのは、最初のレンダリングが終了した後、いつレンダリングをトリガするかを知ることである.これは変異追跡と呼ばれています.これはいつ状態が変わったか、あるいは変異したかを知る必要があります.再レンダリングをトリガするために
re-render
.私たちはすでに不変性を実現しました.私たちのアプリケーションの状態はアプリケーションのどこにも変異がないと確信しています.そして、純関数は完全にその処理ロジックと原則を探しています.どこが変化しているのかが分かりやすくなります.
let state = {
add: 0,
}
funtion render() {
//...
}
function effects(state,action) {
if(action == 'addTen') {
return {...state, add: state.add + 10}
}
return state;
}
function shouldUpdate(s) {
if(s === state){
return false
}
return true
}
state = effects(state, 'addTen')
if(shouldUpdate(state)) {
render();
}
ここには小さなプログラムがあります.ここにstateオブジェクトがあります.オブジェクトは属性addだけです.レンダー関数は正常にプログラムの属性をレンダリングします.彼はプログラムの変更のたびにレンダリングstateオブジェクトをトリガするのではなく、まずstateオブジェクトが変更されているかどうかを確認します.このように、effects関数と純粋な関数があります.この二つの関数は私たちのstateオブジェクトを修正するために使います.新しいstateオブジェクトに戻り、状態を変更すると新しい状態に戻り、修正が必要でない場合は同じ状態に戻ります.
したがって、shuldUpdate関数があります.これは==演算子を使って古い状態と新しい状態が同じかどうかを調べます.それらが異なる場合は、新しい状態を更新するためにレンダー関数を呼び出します.
結論
Web開発におけるこれらの最も一般的な用語を研究し,それらの意味とそれらの用途を示した.もしあなたが実践するなら、これはとても有益です.
もしこの文章に関する問題があれば、私は追加、修正または削除すべきです.いつでも電子メールまたは直接DMをコメントしてください.乾杯!