티스토리 뷰

공부

불변성이란 / this

코딩하는 둥아 2023. 2. 20. 18:53
728x90

불변성 (Immutability)

메모리에 이미 담겨있는 값을 변경하지 않는다.

불변성을 유지한다는 의미는, 함수 외부의 상태에 접근하여 이미 메모리에 할당되어 있는 값을 변경하지 않는다는 의미이다.

ex) 전역 변수 사용하지 않기

 

불변성에 대해 이해를 하려면 Call by value와 Call by reference에 대해 알아야 한다.

 

Immutable type & 값에 의한 호출 (Call by value)

  • string, number, boolean과 같이 원시 자료형을 사용하는 변수들은 모두 값에 의한 호출 방식을 사용하며 immutable(불변) 하다.
  • 함수의 인자로 변수를 넘길 때 해당 변수가 가지고 있는 값을 그대로 복사하여 함수에게 넘겨주는 방식을 의미한다.
  • 따라서 원본 변수와 인자로 넘긴 함수는 다른 메모리 상에 저장되어 있기 때문에, 특정 함수가 인자로 받은 변수를 변경하더라도 원본 변수를 영향을 받지 않는다.
  • 원시 타입은 불변하므로 같은 메모리 영역에서 값의 변경이 불가능하며, 변수에 할당할 때 완전히 새로운 메모리 값을 참조하게 된다.
    • 아래의 예시에서 name 변수에 hello 값을 할당할 때 메모리에 값이 할당된다.
    • newName은 name이 참조하는 메모리를 동일하게 참조한다.
    • name에 hi를 재할당 할 때, 새로운 메모리 참조를 할당하게 된다.
    • 따라서 newName은 name의 값이 변경되더라도 영향을 받지 않는다.
let name = 'hello';
let newName = name;
name = 'hi';

console.log(name); // hi
console.log(newName); // hello

 

참조에 의한 호출 (Call by reference)

  • Array, Object와 같은 객체들은 참조에 의한 호출 방식을 사용하며 변할 수 있는 값이다. (mutable)
  • 함수의 인자로 변수를 넘길 때 값을 복사하여 새로운 메모리 공간에 저장한 후 넘겨주는 Call by value 방식과는 달리, Call by reference는 변수가 가리키고 있는 메모리 공간의 주소를 넘기는 방식을 의미한다.
  • 따라서 특정 함수에서 인자로 전달받은 배열에 원소를 추가하거나 삭제하면 원본 배열의 값이 함께 변하게 되고, 이러한 현상을 불변성이 깨졌다고 한다!
  • 아래의 경우 y는 x의 메모리 참조값을 똑같이 가리킨다. 그래서 x의 name을 변경하면 y 또한 x의 주소를 참조하고 있기 때문에 함께 값이 변경된다. 그리고 x와 y는 같은 메모리 참조를 하고 있기 때문에 x === y에서 true값이 나온다.
let x = {
	name: 'hello'
};
let y = x

x.name = 'hi';
console.log(y.name) // hi
console.log(x === y) // true

 

불변성을 지켜야 하는 이유

  • 무분별하게 상태를 참조하거나 변경하는 경우, 현재 프로그램이 어떻게 돌아가는지 파악하기 힘들어진다. 그리고 이러한 점은 예기치 못한 버그로 이어지게 된다.
  • 상태의 변경을 추적하기 쉽다.

 

불변성을 지키는 방법

  • spread 연산자, map, filter, slice, reducer 등 새로운 객체를 반환하는 메소드 사용하기
    • push, splice 메소드는 원본 배열을 변경시킴
  • immer 라이브러리 사용하기

 

 

this?

  • 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.
  • this는 기본적으로 window임
  • 객체의 메서드를 호출할 때 this를 내부적으로 바꿔줌, 하지만 일반 함수인 경우에는 기본적으로 this가 window임
var obj = {
	a: function() {console.log(this)},
}
obj.a(); // obj

var a2 = obj.a; // obj의 a 메서드를 a2에 꺼내왔기 때문에, 더이상 obj의 메서드가 아님
a2(); // window
  • bind, call, apply 메서드들은 this가 객체를 가리키게 함
var obj2 = { c: 'd' };
function b() {
  console.log(this);
}
b(); // Window
b.bind(obj2).call(); // obj2
b.call(obj2); // obj2 
b.apply(obj2); // obj2
  • 생성자 함수
    • new로 호출하지 않고 그냥 호출하게 되면 일반 함수가 되기 때문에 this가 window를 가리키게 됨.
    • new를 붙이면 this가 생성자를 통해 생성된 인스턴스(person 자신)가 됨
function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.sayHi = function() {
  console.log(this.name, this.age);
}

Person('Name', 25);
console.log(window.name, window.age); // Name, 25

var person = new Person('Hello', 30);
person.sayHi(); // Hello, 30
  • 이벤트 리스너나 제이쿼리 같은 이벤트가 발생할 때, 내부적으로 this가 바뀌게 됨
    • inner함수를 호출할 때에는 this가 window로 설정됨. 따라서 이 문제를 해결하기 위해서는 this를 다른 변수에 저장하던지, 화살표 함수를 사용해야 함
    • 화살표 함수는 this로 window가 아니라 상위 함수의 this를 가져옴
$('div').on('click', function() {
  console.log(this); // <div>
  function inner() {
    console.log('inner', this); // inner Window
  }
  inner();
});
// 변수에 this 저장하기
$('div').on('click', function() {
  console.log(this); // <div>
  var that = this;
  function inner() {
    console.log('inner', that); // inner <div>
  }
  inner();
});

// 화살표 함수 사용하기
$('div').on('click', function() {
  console.log(this); // <div>
  const inner = () => {
  	console.log('inner', that); // inner <div>
  }
  inner();
});

 

 

 

 

References

 

변하지 않는 상태를 유지하는 방법, 불변성(Immutable)

이번 포스팅에서는 순수 함수에 이어 함수형 프로그래밍에서 중요하게 여기는 개념인 에 대한 이야기를 해보려고 한다. 사실 순수 함수를 설명하다보면 불변성에 대한 이야기가 꼭 한번은 나오

evan-moon.github.io

this란 https://www.zerocho.com/category/JavaScript/post/5b0645cc7e3e36001bf676eb

 

https://www.zerocho.com/category/JavaScript/post/5b0645cc7e3e36001bf676eb

 

www.zerocho.com

 

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함