9-1. `name` property of function
class F {
static method1 () {}
method2 () {}
}
function G(){
G.method1 = function (){}
G.prototype.method2 = function (){}
}
const f = new F()
console.log(F.method1.name, f.method2.name)
const g = new G()
console.log(G.method1.name, g.method2.name)
class에서의 name 프로퍼티만 출력된다.
const b = function (){}
console.log(b.name)
이것은 name프로퍼티에 b가 출력된다. 그럼 G라는 함수에 대해서 왜 name 프로퍼티가 출력되지 않는 것일까?
그 이유는
b라는 변수명 하나로 name프로퍼티 값을 설정할 수 있었는데
G라는 함수내에 G.metho1 이런식으로는 프로퍼티 키 값을 설정할 수 있는 방법이 구현되지 않았기 때문에 출력 할 수 없었던 것이다.
반면
class를 사용한 방식에서는 이런 부분이 가능해졌다.
그럼 name의 역할은? 디버깅을 하기 위해서 사용된다.
funtioin a () { console.log(this);}
a.call({})
//{}
a.appply({})
//call apply 는 첫번째 인자로 각각 this를 받는다.
const b = a.bind({a: 1})
//bind는 그냥 실행하지않고 이 결과를 b에 담아라 라는 뜻이다.
//call과 apply는 this 및 인자들을 넘김과 동시에 바로 실행.
//bind는 내가 넘기고 싶은 인자들을 넘기는 것을 바탕으로 새로운 함수를 만든다.
//그래서 b를 실행해야만 결과가 나오게된다.
funtioin a (x,y,z) { console.log(this, x, y, z);}
a.call({}, 1, 2, 3)
a.apply({} [1,2,3])
const b = a.bind({}, 1, 2)
b(3)
const person = {
_name: '재남',
get name () {
return this._name
},
set name (v) {
this._name = v
}
}
const descriptor = Object.getOwnPropertyDescriptor(person, 'name')
console.log(descriptor.get.name)
console.log(descriptor.set.name)
9-2. new.target
function Person (name) {
if (this instanceof Person) {
this.name = name
} else {
throw new Error('new 연산자를 사용하세요.')
}
}
var p1 = new Person('재남')
console.log(p1)
var p2 = Person('성훈')
console.log(p2)
var p3 = Person.call({}, '곰')
console.log(p3)
var p4 = Person.call(p1, '곰')
console.log(p4)
function Person (name) {
console.dir(new.target)
if (new.target !== undefined) {
this.name = name
} else {
throw new Error('new 연산자를 사용하세요.')
}
}
const p1 = new Person('재남')
console.log(p1)
const p2 = Person('성훈')
console.log(p2)
const p3 = Person.call({}, '곰')
console.log(p3)
const p4 = Person.call(p1, '곰')
console.log(p4)
function Person (name) {
const af = n => {
this.name = n
console.log(new.target)
}
af(name)
}
const p1 = new Person('재남')
const p2 = Person('성훈')
```
```js
function Person (name) {
this.name = name
}
function Android (name) {
Person.call(this, name)
}
const p1 = new Android('재남봇')
function Person (name) {
console.log(new.target)
if (new.target === Person) {
this.name = name
} else {
throw new Error('Person 생성자함수를 new로 호출해야 해요!')
}
}
function Android (name) {
Person.call(this, name)
}
const p2 = new Android('재남봇')
9-3. 블록스코프 내에서의 함수 선언과 호이스팅 (브라우저 비교)
if (true) {
a()
function a () { console.log(true) }
}
a
a()
if (true) {
a()
function a () { console.log(true) }
}
if (true) {
a()
function a () { console.log(true) }
if (true) {
a()
function a () { console.log(false) }
}
}
a()
'use strict'
if (true) {
a()
function a () { console.log(true) }
if (true) {
a()
function a () { console.log(false) }
}
}
a()
'use strict'
if (true) {
function a () { console.log(true) }
a()
}
a()
//'strict mode' 가 아닌 경우 ... 'sloppy mode' 에서는: 브라우저마다 다른동작. 예상이안됨
//'strict mode': 함수 선언문도 블락스코프에 갇힌다.
es6에서는 함수선언문을 쓰지 말자.
arrow function
객체에서는 메소드 축약형
생성자 함수를 쓸때는 class
-> 'function'이라는 단어자체가
generator에서만 쓰이게 된다. 오롯이 'function'만 있는 키워드가 등장할 일 자체가 아예 없다.
어떻게든 안쓰는 쪽으로 고민하자.