[TIL]JS 복습, Koans 오답노트

ㅜㅜ·2022년 9월 8일
1

Today I learn

목록 보기
14/77
post-thumbnail

.length 속성

length 속성은 배열과 문자열에서만 사용되고, 객체에서는 사용할 수 없다.
그래서 객체.length를 했을 땐 'undefined'가 반환됨.





method (매서드), this

매서드는 어떤 객체의 속성으로 정의된 함수를 말한다.

const now = {
  me : 'ironman',
  you : 'pepper'
  gethere : function {
  	return [this.me, this.you];
}

gethere은 now 객체의 속성으로 정의된 함수인 '매서드'라고 할 수 있다.
now.gethere() 와 같은 형태로 사용(호출)도 할 수 있다!!

전역 변수에 선언한 함수도 웹페이지에서 window 객체의 속성으로 정의된 함수라고 할 수 있음.
window.와 같은 접두사가 없이도 참조가 가능하기 때문에 생략해서 쓸 뿐!
이렇게 method는 항상 '어떤 객체'의 method임.


this는 호출된 매서드가 '어떤 객체'의 매서드인지를 묻는 역할을 한다.
아래와 같이 affair라는 객체 내에 love라는 매서드를 선언하고, this를 반환하면

let affair = { love : function() {return this}};

affiar.love === affair 이라는 코드에 true라고 반환된다.
(this는 love 매서드가 '어떤 객체'의 매서드인지를 묻기 때문에 affiar가 반환될 것임.)


그러나 화살표 함수는 자신의 this가 존재하지 않는다.
화살표 함수에서 this는 자신을 감싼 정적 범위(lexical context)이다.
일반 변수 조회 규칙(?)을 따르기 때문에 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수 바로 바깥 범위에서 this를 찾는다.

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true

화살표 함수를 사용할 때는 이런 점을 고려해야 한다.

*전역에서는 this는 전역 객체를 가리킴.

MDN으로 가서 더 살펴보기





얕은 복사(shallow copy)와 깊은 복사(deep copy)


1. arr.prototype.slice()

얕은 복사를 수행하기 때문에 중첩 구조 복사를 제대로 수행할 수 없음.

const arr = [1, 2, 3, [4, 5]];
const copied = arr.slice();

copied[3].push(6);
// copied 3번째 인덱스 배열에 들어간 6은 arr에도 생기게 된다. 
// 중첩된 구조 복사가 제대로 안 되었기 때문에 세번째 인덱스 배열은 변경시 원본과 복사본 모두 영향 받는다.


2. Spread Operator

스프레드 연산자도 중첩 구조를 복사하지 못한다.

const arr = [1,2,[3,4]]
const copied = [...arr]

copied[2].push(5) // arr에도 영향을 준다. 


3. Object.assign()

출처 객체들의 모든 열거 가능한 자체 속성을 복사해 객체에 붙여 넣고 해당 객체를 반환 함.

깊은 복사를 위해서는 다른 대안이 필요함.
Object.assign()은 값이 객체의 주소일 때, 그 주소 값만을 복사한다.

참고 링크





arguments

arguments 객체는 함수에 전달된 인수에 해당하는 Array 형태의 객체이다.

arguments 객체는 모든 함수 내에서 이용 가능한 지역 변수입니다. arguments 객체를 사용하여 함수 내에서 모든 인수를 참조할 수 있으며, 호출할 때 제공한 인수 각각에 대한 항목을 갖고 있습니다. 항목의 인덱스는 0부터 시작합니다.

arguments를 통해 '비슷하게' 함수의 전달인자들을 다룰 수 있다.
arguments 객체는 유사 배열을 반환하지만 배열은 아님. (Array.isArray에 넣으면 false 나옴)

function getRestParams(...args){
  return args;
}
function getArguments(){
	return arguments;
}

const restparams = getRestParams("first", "second", "third");
const argumentsobj = getArguments("first", "second", "third");

console.log(restparams) // ["first", "second", "third"]
console.log(Object.keys(argumentsobj))// ['0', '1', '2']
console.log(Object.values(argumentsobj)) //  ['first', 'second', 'third']
console.log(Array.isArray(restparams))// true
console.log(Array.isArray(argumentsObj))//false//배열은 아님!!!

arguments를 실제 array로 변환하기 위해서 Array.from(), 스프레드 연산자 등을 사용할 수 있음.

var args = Array.from(arguments);
var args = [...arguments];




rest/spread 문법 객체 분해에 적용


...user의 위치에 따라 값이 덮어씌워질 수 있다는 점 주의! (문제 답은 블로그에 따로 적지 않기로 했다)
const user = {
      name: "김코딩",
      company: {
        name: "Code States",
        department: "Development",
        role: {
          name: "Software Engineer",
        },
      },
      age: 35,
    };

    const changedUser = {
      ...user,
      name: "박해커",
      age: 20,
    };
//...user로 가져온 값들을 객체에 담는데, 아래에 name과 age를 재할당하는 부분이 있으므로 name과 age의 값이 덮어씌워짐.

    const overwriteChanges = {
      name: "박해커",
      age: 20,
      ...user,
    }; //왜 name, age 값에 변화가 없는가!?!?
    // name, age에 박해커, 20으로 값을 할당했지만, 뒤에 ...usr로 가져온 데이터가 name과 age를 덮어쓰게 된다고 한다!
    // 최종적으로 남는 데이터는 user의 데이터와 동일한 것!

    const changedDepartment = {
      ...user,
      company: {
        ...user.company,
        department: "Marketing",
      },
    };
    //...user로 user의 데이터를 가져오고,
    //company의 department 값만 재할당 된다.

    //...user의 위치에 따라서 내용이 덮어씌워질 수 있군!
profile
다시 일어나는 중

0개의 댓글