함수
function square(x) {
return x*x;
}
객체를 사용하려면 참조변수(주소값이 담겨진 변수)가 필요.
const add = function(num1, nun2){
return num1 + num2
};
함수 리터럴로 정의되는 경우에는 실행 과정중에 함수의 주소값이 참조변수에 대입된다.
그렇기 때문에 호이스팅이 되지않는다. 참조변수는 null값을 갖게됨.
var square = new Function("x", "return x*x");
상속과 관련
스크립트 상속 : 객체간의 프로토타입 체인의 연결로 상속이 이뤄진다.
function만 입력해도 👉 new Function(...) 객체화된다.
Function.prototype. 상속 받는 과정
const nums = [1,2,3,4,5,6,7,8,9];
const nums2 = nums.map(funciton(num){
return num * num;
)};
const nums = [1,2,3,4,5,6,7,8,9];
const nums2 = num.map (x => x * x);
const nums = [1,2,3,4,5,6,7,8,9];
function map(nums, callback) {
const nums2 = [];
for(let i = 0; i < nums.length; i++){
const num = callback(nums[i]);
nums2.push(num);
}
return nums2;
}
const nums2 = map(nums, function(num){
return num * num;
});
const nums3 = map(nums, x => x * x);

입급 객체 / 일등 함수 : 함수형 프로그래밍 방식
function outer(callback){
callbakc();
}
function inner() {
console.log("inner 호출!")
}
outer(inner); //inner가 매개변수로 사용됨.
function outer(callback){
callbakc();
}
outer(function(){
//outer(매개변수); 호출했다. 매개변수로 사용된 함수는 일회용으로서 외부에서는 사용이 불가능하다.
console.log("inner 호출");
});
함수 리터럴로 정의된 this 값은 함수를 호출할 때 결정.
화살표 함수의 this 값은 함수를 정의할 때 이미 결정된 this값으로 결정 즉, 화살표 함수 바깥의 this값이 화살표 함수의 this 값이 됩니다.
const person = {
name : "이름",
age : 40,
showInfo: () =>{
console.log(this);
}
}
person.showInfo(); // This는 window
const person = {
name : "이름",
age : 40,
showInfo: function() {
console.log(this);
}
}
person.showInfo(); //This는 person
inner는 showInfo 함수 호출시에 정의
const person = {
name : "이름",
age : 40,
showInfo: function() {
console.log('showinfo', this);
const inner = () => {
console.log('inner',this);
}; //
inner();
}
}
person.showInfo(); //This는 person
const inner = () => console.log("inner", this); // This는 person
inner();
}
}
showInfo();// 오류
const showInfo = person.showInfo;
person.showInfo(); // This는 person
showInfo(); //window
person.showInfo() === showInfo;


function norm(x) {
var sum2 = sumSquare();
return Math.sqrt(sum2);
function sumSquare() {
sum = 0;
for(var i = 0; i < x.length; i++) sum += x[i]*x[i];
return sum;
}
}
var a = [2,1,3,5,7];
var n = norm(a);
console.log(n);
var s = square(5);
obj.m = function() { ... };
obj.m();
var obj = new Object();
funciton.prototype
함수를 실행하는 기능
func.apply(thisArg,[argsArray]);thisArg: call, apply를 호출할때 사용될 this의 값/ 값을 직접 설정이 가능하다.function add(num1, num2){
return num1+ num2;
}
add.apply
add.apply(this, [10,20])
// 1번째 매개변수는 this의 범위(현재는 window로 설정햇음)
// 2번째 매개변수는 매개변수의 값. 배열로 설정
const person = {name: "이름", age: 40}
function add(num1, num2){
return num1+ num2;
}
add.apply(person, [10,20])
// 1번째 매개변수는 this의 범위(person), (person이 add를 호출한것은 아니다, 단순히 this값만 변경된 것 이다.)
// 2번째 매개변수는 매개변수의 값(인수). 배열로 설정
callapply와 동일하지만 매개변수를 가변적으로 적용할 수 있다.const person = {name: "이름", age: 40}
function add(num1, num2){
return num1+ num2;
}
add.apply(person, 10,20)
bindfunction add(n1,n2){
return n1 + nu2;
}
const add10 = add.bind(this,10); //add메서드의 매개변수 첫번째 n1이 10으로 고정된 함수가 생성되었다.
add10(20); //>num2가 20으로 되었고, 고정된 num1이 30 출력.
[[Prototype]] __proto__ : 프토로타입체인 연결Object.prototype 상속을 받는다.const objA = {a:1, b:2};
const objB = {c:3, d:4};
objB.__proto__ = objA; //B가 A의 자원을 상속받았다.
(function(){
//즉시 실행코드
})(//매개변수);
- - - - - - - - - - - - - - -
(function(){
console.log("즉시실행");
})();
- - - - - - - - - - - - - - -
(function(num1,num2){
return num1 + num2;
})(10,20);
arguments: 지역변수
참고
parameter : 인자(매개변수)
argument : 매개변수로 사용된 값
function add(num1, num2){
console.log(arguments)
}
자바스크립트는 인수를 가변적으로 사용이 가능하다.
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++){
total+=arguments[i];
}
return total;
}
sum(10,20,30,40);
function sum(num1, num2, ...nums){
console.log(nums);
}
sum(10,20,30,40,50); //> 30, 40, 50 만 출력된다.
const nums = [10, 20];
function add(num1, num2){
return num1 + num2;
}
add(...nums);
새로운 객체를 생성할 때 사용
const fruits = ["apple","orange", "mango"];
const fruits2 = [...furits];
fruits === fruits2 //false 새로운 객체를 생성했다.
const nums = [1,2,3,4,5,6,7,8,9];
const [a,b,c] = nums; //비구조화 할당
const nums = [1,2,3,4,5,6,7,8,9];
const [a,b, ...rest] = nums; //나머지연산자
arguments.callee : 함수 객체의 주소값
같은 함수를 연속적으로 내부에서 호출하는 방법
function add(){
console.log(arguments);
console.log(arguments.callee == add);
}
add(); //> true출력
!5 👉 54321
function factorial(num){
if ( num < 1 ) {
ruturn 1;
}
return num * factorial(num - 1) //함수내부에 같은 함수르 또 호출
}
function factorial(num){
factorial.cache = factorial.cache ?? {};
const key = `num_${num}`;
if(factorial.cache[key]){
console.log("캐시 사용");
return factorial.cache[key];
}
if ( num < 1 ) {
ruturn 1;
}
const result = num * factorial(num - 1) //함수내부에 같은 함수를 또 호출
factorial.cache[key] = result;
console.log("캐시 저장");
return result;
}
함수객체 👉 함수 ❌ 👉 실행 ❌
함수객체 👉 번역, 평가 👉 실행 가능 객체(EC - Execution Context)(힙) 👉 스택에서 EC가 실행될때 필요한 자원 할당
var num1 = 10;
function outer() {
var num2 = 20;
function inner(){
var num3 = 30;
return num1 + num2 + num3;
}
console.log(inner());
console.dir(inner);
}
window:
Global EC{
변수 레코드 window 하위 속성으로 변수 레코드 구성
window.num1 = 10;
}
Outer Ec{
변수 레코드 :{
num2 : 20
}
외부 EC 변수 레코드 참조 : Global Ex의 변수 레코드 참조 👉 window 객체 주소
}
Inner Ec{
변수 레코드 : {
num3 : 30 //속박변수, Inner Ec 입장에서는 num2, num1 은 자유변수
}
외부 EC 변수 레코드 참조 : Outer EC 변수 레코드 주소 👉 Outer의 num2값을 가져올수있음.
}
상위객체에 접근할수있는 이유가 유효범위 체인(Scope) 을통해 상위객체의 주소를 참조하기 때문에 상위객체로 한단계씩 접근이 가능하다.
함수가 실행되는 시점에는 지역 변수 또는 함수 선언문으로 선언한 함수 이름이 함수를 평가하는 시점에 선언적 환경 레코드에 기록된 상태입니다. 따라서 변수 또는 함수 선언문이 함수 안의 어떤 부분에 위치하더라도 함수 전체에서는 사용할 수 있습니다.
함수를 호출한 객체의 주소.
window:
Global EC{
변수 레코드 window 하위 속성으로 변수 레코드 구성
window.num1 = 10;
this 바인딩 : window 객체의 주소
}
Outer Ec{
변수 레코드 :{
num2 : 20
}
외부 EC 변수 레코드 참조 : Global Ex의 변수 레코드 참조 👉 window 객체 주소
this 바인딩 : 함수를 호출한 객체의 주소
}
Inner Ec{
변수 레코드 : {
num3 : 30
}
외부 EC 변수 레코드 참조 : Outer EC 변수 레코드 주소 👉 Outer의 num2값을 가져올수있음.
}
this는 호출할 때 this의 값이 결정된다
함수를 정의한다고 해도 this 값은 결정 ❌ 👉 실행 👉 EC 구성시 this값이 결정(호출한 객체의 주소값)
add는 전역변수이기 때문에 this의 값은window이다.
function add(){
console.log(this);
}
add();
const person = {name : "이이름", age : 40};
person.add = add;
person.add === add() // true
person; //? {{name : "이이름", age : 40, add:f};
add(); // this의 값은 window
person.add; // this의 값은 person
반환값이 함수객체이기 때문에
function(num2) 함수객체의 주소를 반환한다. 그렇기때문에 num2값에 20이 들어간다.
add2가 add(10)을 참조하기 때문에 힙영역에있는 10은 삭제가 되지않고 영역에 남아있다.
num1의 10이 function(num2)에 속박되어있기 때문에 클로저라고한다.function add(num1) { return function(num2){ return num1 + num2; }; } const add2 = add(10); //add2 에는 function(num){return num1+ num2}의 주소값을 받는다. add2(20); //> 30
고차원함수
고차원함수와 팩토리함수는 클로저가 있기 때문에 가능
클로저로 인해 값들이 계속 유지중이고 스코프를 통해 값들이 끊겨있지 않기 때문에 고차원으로 함수가 가능하다.function add(num1){ return function(num2){ return function(num3){ return num1 + num2 + num3; } } }
const add = num1 => num2 => num3 => num1+num2+num3;
add(10)(20)(30);
//>60
### 팩토리함수
>클로저로 인해 계속해서 함수를 생성할수있다.
```js
function add(num1) {
return function(num2){
return num1 + num2;
};
}
const add2 = add(10); //새로운 함수 생성
const add3 = add(20); //새로운 함수 생성
const add4 = add(30); //새로운 함수 생성
add2(20); //> 30
var : 지역 - 함수 지역
호이스팅으로 인해 전역 이름 공간 오염 👉 전역변수 사용 지양
var i = 100; //매우 중요한 숫자
var i = 10;
i; //> 10으로 나옴
var i = 100; //매우 중요한 숫자
for( var i = 0 ; i < 10; i++){
}
i; // > 10
이를 해결하기 위해 let,const 탄생
let : 변수 선언자
const : 상수 선언자
👉 지역범위{...}로 변경
let i = 100;
{
let i = 10;
}
console.log(i) //> 100
let i = 100;
for(let i = 0; i < 10; i++){
}
console.log(i); //> 100
const str = 'abc;
str = 'def'; //오류가 발생 const는 상수이기때문에 값 변경이 불가능.

변수는 const로 정의하고, 변경이 필요한 경우만 let으로 선언
kakao.maps ...
var chj = chj ?? {}
chj.popup = {
show(){
},
close(){
}
}
chj.popup.close();
즉시실행 함수, 모듈 패턴
const order = (function() {
const orderNum = 100;
return {
getNum(){
return orderNum;
}
};
})();
1) 객체간의 상속, 프로토타입 기반 상속(프로토타입 체인 연결)
2) 프로토타입 체인의 연결 관계로 상속을 나타낸다.
[[Prototype]] 프로토타입 체인
__proto__ : 프로토타입 체인 변경 👉 호환성문제가 존재 👉 Object.setPrototypeOf(...) 프로토타입 체인 연결
const objA = {a:1, b:2};
const objB = {c:3, d:4};
objB.setPrototypeOf(objB, objA);
objB; //{a:1, b:2} {c:3, d:4}
생성자 함수 객체 👉 객체 생성 과정은 함수 객체의 prototype 객체의 상속 과정!
function Person(){
this.name = "이이름";
this.age = 40;
}
const p1 = new Person(); //Person.prototype 상속관계
3) 생성자 함수의 this를 생성할 객체를 변경하고 호출함으로서, 값의 초기화
function Person(){
this.name = "이이름";
this.age = 40;
}
Person(); // this는 window
name; //window.name
age; //window.age
function Person(){
this.name = "이이름";
this.age = 40;
}
const p1 = {}
Person.apply(p1);//Person의 this값을 p1으로 변경 (p1이 Person을 호출)
p1.name;
p1.age;