금요일은 몸이 안좋아서 쉽니다
월수금 알고리즘 & 자료구조 + 운영체제 + 구현
화목토 SQL + 네트워크 + 코어자스 + 구현
다른 대부분 객체지향 언어에서 this는 클래스로 생성한
인스턴스 객체를 의미한다.
반면 자바스크립트에서 this는어디서든 사용이 가능하고, 상황에 따라 바라보는 대상이 달라지는데 예상과 다르게 엉뚱한 대상을 보는 경우도 있어서 만약 오류가 생겼을 때 정확한 작동방식을 모른다면 원인을 해결하기 힘들다.
함수와 객체(메서드) 구분이 느슨한 자바스크립트에서 this는 실질적으로 이 둘을 구분하는 거의 유일한 기능이다.
실행 컨텍스트가 생성될 때 결정 = 함수를 호출할 때 결정
전역 컨텍스트를 생성하는 주체 = 전역객체
브라우저 환경: Window
Node js: global
참고: 전역변수를 선언하면 자바스크립트 엔진은 전역객체의 프로퍼티로 할당
자바스크립트 모든 변수는 특정 객체의 프로퍼티로서 동작함! (전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다)

var a = 1 전역변수 선언
window.a = 1 전역 객체 프로퍼티로 선언
둘다 표현하는 내용은 같지만 전자는 해당 프로퍼티의 configurable 속성 (변경 및 삭제 가능성)을 false로 정의함
함수로서 호출: 그 자체로 독립적인 기능 수행메서드로서 호출: 자신을 호출한 대상 객체에 관한 동작을 수행독립성어떤 함수를 호출할 때 그 함수이름(프로퍼티 명) 앞에 객체가 명시돼 있는 경우 메서드로 호출한 것이고, 그렇지 않은 모든 경우는 함수로 호출한 것임! -> 함수 앞에 .이 있는지 여부만으로 간단하게 구분 가능함! (물론 대괄호 표기법의 경우에도 메서드임)
var func = function (x) {
console.log(this, x);
};
func(1); // 함수로 동작
var obj = {
method: func
};
obj.method(2) // 메서드로 동작
메서드를 '객체의 프로퍼티에 할당된 함수'로 이해하곤 하는데 반은 맞고 반은 틀린 소리
그 자체로 무조건 메서드가 되는 것이 아니라 객체의 메서드로서 호출할 경우에만 메서드로 동작하고 그렇지 않으면 함수로 동작함
호출한 주체에 대한 정보가 담긴다.. 앞 객체가 곧 this가 된다.)동일한 함수라도 다른 객체에서 호출했다면 'this’가 참조하는 값이 달라진다.
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// 별개의 객체에서 동일한 함수를 사용함
user.f = sayHi;
admin.f = sayHi;
// 'this'는 '점(.) 앞의' 객체를 참조하기 때문에
// this 값이 달라짐
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (점과 대괄호는 동일하게 동작함)
어떤 함수를 함수로서 호출할 경우에는 this가 지정되지 않는다.
this에는 호출한 객체에 대한 정보가 담기는데 함수로서 호출한다 = 호출 주체 (객체지향 언어에서 객체)를 명시하지 않고 개발자가 직접 관여해서 실행한 것이라서 호출 주체의 정보를 알 수가 없는 것!
실행 컨텍스트를 활성화할 당시에 this가 지정되지 않은 경우 this는 전역객체를 바라봄.
따라서 함수에서의 this는 전역 객체를 가리킨다.

이 분 왈 그걸 설계상 오류라고 함....
메서드 내부에서 정의하고 실행한 함수에서 this 대박 많이 헷갈림
더글라스가 지적한 설계상 오류로 인해 실제 동작과 다르게 예측하게 됨
그러나 내부함수 역시 이를 함수로서 호출했는지 메서드로서 호출했는지만 파악하면 this 값을 정확히 맞출 수 있음!

line 1: 객체 생성
line 15: obj1.outer() 호출
line 3: obj1 객체 정보 출력
line 4: 호이스팅된 변수 innerFunc 는 outer 스코프 내에서만 접근할 수 있는 지역변수. 이 지역 변수에 익명 변수 할당함
line 7: innerFunc() 함수 호출 -> window 출력
line 12: obj.innerMethod() 메서드 호출 obj2 출력
-> this 마지막 점 앞의 객체인 innerobj가 바인딩 됨

변수를 검색하면 우선 가장 가까운 스코프의 L.E를 찾고 없으면 상위 스코프를 탐색하듯이 this 역시 현재 컨텍스트에 바인딩된 대상이 없으면 직전 컨텍스트 this를 바라보게 하고 싶을 경우
=> (주로 이름이self인) 변수 활용
var obj = {
outer: function () {
console.log(this); // (1): obj1
var innerFunc1 = function () {
console.log(this); // (2): window (3): obj2
};
innerFunc1();
var self = this;
var innerFunc2 = function() {
console.log(self);
};
innerFunc2();
},
};
obj.outer();
함수 내부에서 this가 전역 객체를 바라보는 문제를 보완, this를 바인딩하지 않는 화살표 함수 도입
var obj = {
outer: function () {
console.log(this); // (1): { outer: f}
var innerFunc = () => {
console.log(this); // (2): { outer: f}
};
innerFunc();
},
};
obj.outer();
this를 바인딩하지 않는다!
생성자 함수: 어떤 공통된 성질을 지니는 객체들을 생성하는 데 사용하는 함수
객체지향 언어에서는 생성자를class클래스로 만든 객체를instance라고 한다.
프로그래밍적으로생성자는 구체적인인스턴스를 만들기 위한 틀임!
var Cat = function (name, age) {
this.bark = "meow";
this.name = name;
this.age = age;
};
var choco = new Cat("초코", 3);
console.log(choco); // Cat { bark: 'meow', name: '초코', age: 3 }

line 6: 생성자 함수 내부에서 this는 choco 인스턴스를 가리킴
함수에 생성자 역할 부여
new 명령어와 함께 함수 호출하면 해당 함수가 생성자로 등장함
어떤 함수가 생성자 함수로서 호출된 경우 내부에서 this는 새로 만들 구체적인 인스턴스 자신이 된다.
(붕어빵 틀을 만들고 붕어빵을 만들었는데 안에 팥앙금이 들었다.)
__proto__라는 프로퍼티가 있는 객체(인스턴스)를 만든다 (-> 이후 챕터 6에서 따로 볼 것임!!)정리
- 전역공간에서 this는 전역객체 (브라우저: window, Node.js에서는 global) 참조
- 어떤 함수를 메서드로서 호출한 경우 this는 메서드 호출주체 (메서드명 앞의 객체)를 참조한다.
- 어떤 함수를 함수로서 호출한 경우 this는 전역객체를 참조함. 메서드 내부함수에서도 같다.
- 콜백 함수 내부에서 this는 해당 콜백 함수 제어권을 넘겨받은 함수가 정의한 바에 따르며, 정의하지 않은 경우에는 전역객체를 참조한다.
- 생성자 함수에서의 this는 생성될 인스턴스를 참조한다.
Array.prototype.forEach(callback [, thisArg]), Set, Maphttps://ko.javascript.info/call-apply-decorators
Function.prototype.call(thisArg,[, arg[,arg2[, ...]]])
메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령어
이때 call 메서드의 첫번째 인자를 this로 바인딩하고, 이후 인자들을 호출할 함수의 매개변수로 한다.
const obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
},
};
obj.method(2, 3); // 1 2 3
obj.method.call({ a: 10 }, 2, 3); // 10 2 3
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
Function.prototype.apply(thisArg[, argsArray])
call메서드와 기능적으로 완전히 동일하다.
call메서드는 첫번째 인자를 제외한 나머지 모든 인자들을 호출할 함수의 매개변수로 지정하는 반면,
apply메서드는 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정한다.
(func의 this를 context로 고정해주고, 유사 배열 객체인 args를 인수로 사용할 수 있게 해준다.)
-> call과 apply의 문법적 차이는 call이 복수 인수를 따로따로 받는 대신 apply는 인수를 유사 배열 객체로 받는다는 점이다
인수가 이터러블 형태라면 call을, 유사 배열 형태라면 apply를 사용
배열같이 이터러블이면서 유사 배열인 객체엔 둘 다를 사용할 수 있는데, 대부분의 자바스크립트 엔진은 내부에서 apply를 최적화 하기 때문에 apply를 사용하는 게 좀 더 빠르다.
func.call(context, ...args); // 전개 문법을 사용해 인수가 담긴 배열을 전달하는 것과
func.apply(context, args); // call을 사용하는 것은 동일
전개 문법 ...은 이터러블 args을 분해 해 call에 전달
apply는 오직 유사 배열 형태의 args만 받음
-> 유사배열객체에 call또는 apply 메서드를 사용해서 배열 메서드 적용가능! (책 참고)
문자열 (length 프로퍼티가 읽기 전용)이기 때문에 원본 문자열에 변경을 가하는 메서드 (push, pop, shift, unshift, splice 등)는 에러를 던진다.
const func = function (a, b, c) {
console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
const obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
},
};
obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
사실 call/apply를 이용해 형변환하는 것은 this를 원하는 값으로 지정해서 호출한다라는 의도와 다소 동떨어지는 활용법임. 따라서 숙련된 사람 아니면 코드만 보고 무슨 의도인지 파악하기 어렵다. 이를 극복하기 위해서

add 메서드는 arguments를 배열로 변환해서 args 변수에 담고, 그 다음 라인6에서 배열을 순회하면서 콜백 함수 실행함.
라인 15에서 60, 85, 95를 인자로 삼아 add메서드를 호출하면 세 인자를 배열로 만들어 forEach 메서드 실행됨.
콜백함수 내부에서 this는 add메서드에서의 this가 전달된 상태이므로 add메서드의 this(report)를 그대로 가리키고 있음.
-> 배열 세 요소를 순회하면서 report.sum, report.count 값이 차례로 바뀌고 순회를 마치면 콘솔에 출력됨.
function Counter() {
this.sum = 0
this.count = 0
}
Counter.prototype.add = function(array) {
array.forEach(function(entry) {
this.sum += entry
++this.count
}, this)
// ^---- 주의
}
const obj = new Counter()
obj.add([2, 5, 9])
obj.count
// 3
obj.sum
// 16
thisArg 매개변수(this)를 forEach()에 제공했기에, callback은 전달받은 this의 값을 자신의 this 값으로 사용할 수 있다.
참고: 화살표 함수 표현식을 사용하여 함수 인수를 전달하는 경우 thisArg 매개변수는 화살표 함수가 this 값을 렉시컬(lexical, 정적) 바인딩하기에 생략될 수 있다.

→ Here's example where an object obj is declared with the greet method.
→ Because the object obj is calling the greet function (obj.greet()), you can see that the 𝐭𝐡𝐢𝐬 in that function references obj.
→ This is what I mean by an object calling a function.

→ Remember as I stated earlier, this is determined by the object calling the function
→ The greet function is assigned to hello, and because hello() is called directly, the 𝐭𝐡𝐢𝐬 in hello will point to the global Window object.
authorSelect: function (authors, author_id) {
var tag = "";
for (var i = 0; i < authors.length; i++) {
let selected = "";
if (authors[i].id === author_id) {
selected = "selected";
}
tag += `<option value="${authors[i].id}">${authors[i].name}</option>`;
}
return `
<select name="author">
${tag}
</select>
`;
},
반복문을 통해 작성자 목록을 만들면서 두 번째 매개 변수 author_id와 같은 값을 만나면 해당 에 'selected'를 추가
<select name = "author">
//생략
<option value="3" selected> dudda </option>
걍 라이브러리로 빼는 노가다임 Express 프레임워크 활용으로 넘어감!
책에 나온 내용 뭔가 구식같아서 걍 구글링해서 이 문서 따라함
https://expressjs.com/en/starter/installing.html -> express 공식문서 설치
sudo lsof -i :3000 (띄어쓰기 조심)
sudo kill -9 PID
const express = require("express");
const app = express();
app.get("/", (req, res) => res.send("Hello World~!"));
app.listen(3000, () => console.log("Example app listening on port 3000"));
http://expressjs.com/en/5x/api.html#express

http://expressjs.com/en/5x/api.html#app.get
여기서 api 사용법 볼 수 있음
app.method( PATH , HANDLER ) 의 구조로 되어 있으며yarn test로 노드 실행하고 싶어서 찾아봄
"scripts": {
"test": "node main.js"
},
이캐 하면 됨
아니 근데 예제코드 계속 이런식으로 루프 돌리는데요

대체 왜 포문안쓰는거지 이유가 잇나 나중에 찾아봐야지

변수에는 res 적어놓고 response 이렇게 적어둠.. ㅎ
실제 적용...
app.get("/page/:pageId", (req, res) => {
res.send(req.params);
});

사용자가 요청한 url을 req.params을 이용해 키:값 형태로 가져올 수 있다.
res.send() 요거 공식문서 보고 다르게 써보는데 왜 오류? 개빡침 내일 다시 볼거임 휴..
const solution = (nums) => {
const allowedPickCount = nums.length / 2;
const pocketmonType = [...new Set(nums)];
const pickedPocketmon = pocketmonType.slice(0, allowedPickCount);
return pickedPocketmon.length;
};
혹시 뭔가 낭비 (array 길이 범위 이상으로 slice하면 연산에서 손해 보는 것이 있는가) 있을까봐 찾아봤는데
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
arr.slice([begin[, end]])
end가 생략되면 slice()는 배열의 끝까지(arr.length) 추출합니다.
만약 end 값이 배열의 길이보다 크다면, slice()는 배열의 끝까지(arr.length) 추출합니다.
퍼펙트
// 다른 솔루션
function solution(nums) {
const numLen = nums.length;
const setLen = [...new Set(nums)].length;
return numLen / 2 >= setLen ? setLen : numLen / 2;
}
아싸 내가 더 깔끔하게 풀었따!!!!!!!
아 근데 시간복잡도가 내가 손해네..
둘다 O(n)이긴 한데 리턴할 때 다른 사람 풀이는 연산때려서 나오는거구 나는 slice 써서 좀 더 속도 차이날 듯 함
속도차이 어떻게 나나 봐야겠다 (블로그를 너무 의식의 흐름대로 적나..)
내풀이

저 사람 풀이

내 추측으로 연산이 작은 경우는 (~테케 15) 속도 엇비슷하게 난다.
테케 16, 17, 18 보믄 아주 찔끔 차이난다 (진짜 바보같이 말하네;)
아무튼 slice()는 문서를 보면 얕은 복사본을 새로운 배열 객체로 반환한다. 원본 배열은 바뀌지 않는다
라고 하는데 한마디로 새로운 배열을 만든다 = 깊은 복사를 하므로.. 아주 조오오오금 영향이 있어보인다.
그래도 막 큰 차이는 없는 것 같기도 함.
https://ko.wikipedia.org/wiki/MAC_%EC%A3%BC%EC%86%8C
물데네전세표응..

같은 네트워크 상에 존재하는 장비끼리 데이터 전달 (오류 제어, 흐름 제어)
맥북에서 MAC주소 확인하는 법: 네트워크 - 고급 - 하드웨어드가면 있음
대충 AA:AA:AA:AA:AA 형태 (총 48비트 주소 공간)


사진 출처
목적지, 출발지 주소 각 6바이트씩 + 이더넷 타입 (data frame 영역에 있는 상위계층 프로토콜이 뭔지(ex. tcp/ip 헤더) 정보를 알려줌) 2바이트
이더넷 타입 추가 정보: 만약 ip 계층 프로토콜이 ipv4이면 0 8 0 0
arp면 0 8 0 6
이더넷 프로토콜은 ping을 이용할 때 또는 다른 통신을 이용할 때 모두 사용하게 된다. 운영체제가 알아서 설정해준다. 참고로 ping 명령어로 통신하면 [ethernet][ip][icmp] 이렇게 3개의 프로토콜로 하나의 패킷을 만들어서 통신함!
오전오후밤월수금 알고리즘 & 자료구조 + 운영체제 + 구현
화목토 SQL + 네트워크 + 코어자스 + 구현
const getRandomNumber = (input) => {
let answer = [...input];
while (answer.length < 6) {
const num = Math.floor(Math.random() * (45 - 1)) + 1;
if (answer.includes(num)) {
continue;
}
answer.push(num);
}
return answer.sort((a, b) => a - b);
};
console.log(getRandomNumber([]));
// 반자동