: 변수가 선언된 위치에 따라 자신이 유효한 범위
- JavaScript는 funcion-level scope가 기본
: var- 다른 언어(c, java) : block-lavel scope가 기본
var x = "Hello"; // 전역변수 - global scope
// 함수 선언문
function foo() {
var x = "World"; // 지역변수 - local scope
function bar() {
var x = "haha"; // 지역변수 - local scope
console.log(y);
// 변수를 찾을 때 현재 scope로부터 상위 scope로
// 올라가면서 변수를 찾는다
// scope는 서로 포함관계에 있을 수 있음
}
console.log(x); // x?
// JavaScript Engine이 이 x는 과연 x인가?
// identifier resolution(식별자 결정) => Scope
// 두 개의 x는 이름은 같지만 scope가 다름
// scope => namespace
}
foo();
console.log(x);
상위 scope가 하위 scope를 포함할 수 있음(포함관계)
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x); // ?
}
foo();
① 함수를 어디에서 호출
했는지에 따라 결정 (Dynamic Scope)
② 함수를 어디에서 정의
했는지에 따라 결정 (Static Scope - lexical scope)
: 여기서 선언된 변수를 전역변수
라고 함
: Global Variable
: Javascript는 전역객체
① browser 환경에서 실행 가능 : window 객체
② Node.js 환경에서 실행 가능 : global 객체
=> ① ② 모두 불편, globalThis(ES11)
① 가독성이 나빠짐 -> 의도치않은 문제 발생
② 생명주기가 길어서 resource를 오랜기간 소모함
③ scope chan의 최상위에 위치하기 때문에 변수 검색속도가 가장 느림
④ 여러개의 JS파일에 의해 전역 공유
① IIFE (즉시 실행 함수)
② Module을 이용 ( Module scope)
Internal slot(내부 슬롯) -> 변수
Internal method(내부 메소드) -> 함수
: [[ ]]
: 이런 내부 slot과 내부 method는 개발자가 직접 사용할 수 X -> JavaScript Engine에 의해 사용됨
-> 하지만 필요에 의해 간접적으로 이 slot과method를 사용할 수 있음
: 내부 slot(변수) : property로 붙어있음
: 직접적인 사용은 안 됨
: 간접적인 사용은 허용 : __proto__
const obj = {
// property
myName : '홍길동',
myAge : 20
}
obj = {};
const obj = {
// property
myName : '홍길동',
myAge : 20
}
console.log(obj);
// console.log(obj);
// console.log(obj.[[Prototype]]); //에러
console.log(obj.__proto__); // 이건 가능
: 객체의 구성요소
: key : value의 쌍으로 구성
: attribute를 가지고 있음 (4개 존재)
[[value]] : property의 value
[[writable]] : true, false : 고치는? 업데이트
[[Enumerable]] : true, false : 나열될 수 있느냐
[[Configurable]] : true, false
Object 생성자 함수
: JavaScript의 모든 함수 중 최상위에 위치
: JavaScript 함수 -> 객체 -> property를 가짐
Object.getOwnProperty Descriptor-->property()
const person = {
name : '홍길동',
age : 20
}
console.log(person);
console.log(Object.getOwnPropertyDescriptors(person));
// 객체를 다른 방식으로 만들어 보자
const person = {}
Object.defineProperty(person, 'firstName', {
value : '홍',
writable : true,
enumerable : true,
configurable : true
})
const person1 = {
firstName : '홍'
}
console.log(person.firstName);
writable : false 로 바꾸면,
내부 slot
내부 method
=> [[ ]] ': 직ㄱ접적ㅇ니 사용 안됨
기억해야하는 대표적인 [[Property]]
: JS 어쩌구...
bult-in 생성자함수
Object,String, Number, Boolean, Function, Array, Date ...
user define 생성자 함수
cosnt obj = {}
=> literal 객체 생성
객체를 ??할 때 생성자 함수를 이용
// new라는 키워드로 생성자 함수를 호출할 수 있음 !
const person = new Object() // {}
person.name = '홍길동';
person.age = 20;
console.log(person);
const strObj = new String('소리없는 아우성')
console.log(typeof strObj); // object
console.log(strObj);
const strObj = new String('소리없는 아우성')
console.log(typeof strObj); // object
// 유사배열객체가 만들어짐.
// 유사배열객체는 진짜배열과 동일한데, 대신 함수를 가지고 있지 않아서
// 사용하는데 제약이 있음
// 대신 index와 같은 기능은 있어서
// 배열처럼 사용 가능
console.log(strObj);
const strObj1 = {
name : '홍길동'
}
console.log(typeof strObj1); // object
console.log(strObj1);
const numObj = new Number(100);
console.log(numObj);
const dateObj = new Date();
console.log(dateObj);
: 동일한 property를 가지는 객체를 여러개
: 생성자함수를 정의한 후 new
를 이용하여 객체 생성
: 그럼, 생성과 함수는 마치 Java class처럼 이용할 수 있음
: ES6(ECMA 2015)에c class 개념과 keyword됨
하지만, 실제 동작은 생성자 함수로 동작함
① 일반 함수 내에서 this -> 전역객체(window)
② 메소드형태로 실행된 함수내에서 this -> method를 호출한 instance(Java)
③ 생성자 함수 내에서 this -> 그 생성자
함수는 reference type -> Object(객체) - property의 집합
// 사용자 정의 생성자 함수
// 생성자 함수는 관용적으로 첫글자를 대문자로 씀
// 함수 선언문
function Person() {
}
const person1 = new Person();
const person2 = {}
console.log(person1);
console.log(person2);
/ 일반적인 생성자 함수의 형태를 알아보자
// 1. this keyword가 나옴
// this의 의미는 이 생성자 함수로 만들어지는
// 객체를 지칭
// 2. return구문이 없음
// 묵시적으로 생성된 객체를 리턴함
// 그래서 return을 쓰지 않음
function Circle(radius) {
this.radius = radius;
this.getDiameter = function() {
return 2 * 3.14 * radius;
}
}
let circle1 = new Circle(5); // 객체 생성!
let circle2 = new Circle(10); // 객체 생성!
console.log(circle1);
console.log(circle1.getDiameter());
// 생성자 함수는 new keyword와 함께 사용되고
// 그리고 생성자 함수는 그 안에 return구문이 없음
// 그럼에 불구하고 만들어진 객체가 묵시적으로 리턴됨
function Circle(radius) {
this.radius = radius;
}
const circle1 = Circle(10); // 일반 함수로 호출
console.log(circle1);
// 함수가 호출됐는데 리턴이 없으면?
// 묵시적으로 undefined가 리턴됨
console.log(circle1); // undefined
function Circle(radius){
this.radius = radius;
}
const circle1 = Circle(10);
console.log(window.radius); // 10
함수는 reference type -> Object(객체) - property의 집합
: 따라서 함수에도 property를 등록할 수 있음
특별히 함수객체는 <내부slot 2개, 내부method 2개>를 기본적으로 제공(항상 2개를 가지는 건 아님)
- 내부 method
:[[Call]]
모든 함수 객체가 다 가지고 있음
:[[Construct]]
객체를 만들 수 있는 애들만 가지고 있음
// 함수선언문
function foo() {
}
// 첫번째 phase에서 foo라는 변수 생성(묵시적으로)
foo.myName = '홍길동'
foo.myFunc = function(){
console.log(this);
}
console.log(foo.); // 홍길동
foo.
function foo(){
}
// foo는 일반함수로 호출 가능하기 때문에
// 기본적으로 [[call]]를 가지고 있는 함수.
// foo는 callable
foo(); // 이렇게 호출하면... 내부적으로 [[Call]]이 호출됨
var myVar = 100;
myVar; // [[Call]]이 없기때문에 오류 발생
[[Call]]
을 가지고 있는 함수 객체 -> Callable
[[Construct]]
를 가지고 있는 함수 객체 : constructor
① 익명으로, literal로 생성 가능한 객체
② value로 판단 가능 -> 변수와 자료구조에 저장 가능
③ 함수를 이용할 때 인자로 넘길 수 있는 객체
④ 함수의 return값으로 수 있는 객체 : 클로져
=> JavaScript의 함수(function)는 일급객체(일급함수)
함수의 형태(property)를 확인하기 위해
console.log(~)
를 사용했는데,
내부를 조금 더 들여다보기 위해console.dir(~)
var obj = {
name : '홍길동'
}
console.log(obj);
console.dir(obj);
function square(number) {
return number * number;
}
console.log(square);
console.dir(square);