객체안에 저장된 함수
메서드는 this로 객체를 참조한다
const user = {
name: "yu",
// 1
sayHi: function () {
console.log("hi", this.name);
}
// 2
sayHi() {
console.log("hi", this.name);
}
}
함수를 호출한 객체
this는 함수가 호출될 때(런타임) 결정된다. (누가 호출했냐에(콘텍스트)따라 달라진다)
메서드를 하나만 만들어서 여러 객체에서 재사용이 가능하다 (객체에 따라 this값이 다르기 때문)
function commonSayHi() {
console.log(this.name);
}
const yu = { name: "yu" };
const stephen = { name: "stephen" };
yu.f = commonSayHi;
stephen.f = commonSayHi;
// 동일한 함수라도 다른 객체에서 호출했다면 'this’가 참조하는 값이 달라집니다
yu.f(); // yu
stephen.f(); // stephen
위에서 봤다시피, this는 함수를 실행하는 객체에따라 달라지므로 실수하기 쉽다
간단한 버전의 함수로, 익명함수다
this가 없다
call()
或 apply()
方法调用一个函数时,只能传递参数(不能绑定this),第一个参数会被忽略function fun() {
this.num = 123;
}
const arrFuc = () => {
this.num = 123;
};
const f1 = new fun();
console.log(f1.num); // 123
const f2 = new arrFuc(); // Cannot set properties of undefined (setting 'num')
arguments가 없다
// 일반함수
function fun() {
console.log(arguments); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
fun(1, 2, 3);
// 화살표함수
const arrFun = () => {
console.log(arguments); // Uncaught ReferenceError: arguments is not defined
};
fun(1, 2, 3);
super이 없다
(외부함수에서 가져옴)function func() {
this.name = "b";
return {
name: "a",
sayHi: function () {
console.log(this.name);
}
};
}
// 위의 func과 같다
function simpleFunc() {
this.name = "b";
return {
name: "a",
sayHi() {
console.log(this.name);
}
};
}
function arrowFunc() {
this.name = "b";
return {
name: "a",
sayHi: () => {
console.log(this.name);
}
};
}
const fun1 = new func();
fun1.sayHi(); // a
const fun2 = new arrowFunc();
fun2.sayHi(); // b
var dog = {
lives: 20,
// 화살표함수
jumps: () => {
this.lives--; // cannot read properties of undefined
},
// 일반함수
jumps: function () {
this.lives--;
return this;
}
};
dog.jumps();
배열처럼 보이는 가짜배열 (예) obj, 함수의 arguments
function arrayLike() {
console.log(arguments);
}
arrayLike(4, 5, 6); // Arguments [4, 5, 6, callee, Symbol]
유사배열은 일반배열의 메소드
(map, filter, forEach..)를 직접적으로 사용할수 없다
Array.from(nodes).forEach(function(el) { console.log(el) });
Array.prototype.forEach.call(nodes, function(el) { console.log(el); });
Array.isArray()
instanceof (판별할객체 instanceof constructor)
call, apply, bind
var example = function (a, b, c) {
return a + b + c;
};
example(1, 2, 3);
example.call(null, 1, 2, 3);
example.apply(null, [1, 2, 3]);
call은 보통함수와 똑같이 인자를 넣고,
apply는 [인자] 이렇게 하나의 배열로 만들어 넣는다
this를 바꿀수 있다
const user = {
name: "yu",
yell: function () {
console.log(this.name);
}
};
const user2 = {
name: "stephen"
};
user.yell(); // yu
user.yell.apply(user2); // stephen
this가 가리키는게 user에서 user2로 변했다.
yell은 user의 메소드인데도, user2이 사용했다.
즉 다른 객체의 함수를 자기 것마냥 사용할 수 있다
일반함수에서 this를 바꿀때
유사배열이 일반배열 메소드를 쓰고싶을때
function example() {
console.log(arguments); // 1, string, true
console.log(arguments.join("")); // arguments.forEach is not a function
console.log(Array.prototype.join.call(arguments)); // 1,string,true
}
example(1, "string", true);
bind 함수는 함수가 가리키는 this만 바꾸고 호출하지는 않고 함수만 반환한다.
위의 예시와 비교하면
const user = {
name: "yu",
yell: function () {
console.log(this.name);
}
};
const user2 = {
name: "stephen"
};
user.yell(); // yu
// user.yell.apply(user2); // stephen // apply, call
const user2Fuc = user.yell.bind(user2); // bind는 만 바꾸고 호출하진 않는다
user2Fuc();
셋다 this를 바꾸지만,
bind는 함수를 반환하지 바로 실행하진 않는다.
call(this, 1, 2, 3)은 bind(this)(1, 2, 3)과 같다.