Function.prototype.bind()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since 2015ë 7ì.
bind() ë©ìëê° í¸ì¶ëë©´ ìë¡ì´ í¨ì를 ìì±í©ëë¤. ë°ê²ëë 첫 ì¸ìì valueë¡ë this í¤ìë를 ì¤ì íê³ , ì´ì´ì§ë ì¸ìë¤ì ë°ì¸ëë í¨ìì ì¸ìì ì ê³µë©ëë¤.
ìëí´ ë³´ê¸°
const module = {
x: 42,
getX: function () {
return this.x;
},
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42
구문
func.bind(thisArg[, arg1[, arg2[, ...]]])
매ê°ë³ì
thisArg-
ë°ì¸ë© í¨ìê° ëì í¨ì(target function)ì
thisì ì ë¬íë ê°ì ëë¤. ë°ì¸ë© í¨ì를newì°ì°ìë¡ ìì±í ê²½ì° ë¬´ìë©ëë¤.bind를 ì¬ì©íì¬setTimeoutë´ì ì½ë°± í¨ì를 ë§ë¤ ë,thisArgë¡ ì ë¬ë ìì ê°ì ê°ì²´ë¡ ë³íë©ëë¤.bindí ì¸ì(argument)ê° ì ê³µëì§ ìì¼ë©´ ì¤í ì¤ì½í ë´ìthisë ìë¡ì´ í¨ììthisArgë¡ ì²ë¦¬ë©ëë¤. arg1, arg2, ...-
ëì í¨ìì ì¸ì ìì ì¬ì©ë ì¸ì.
ë°í ê°
ì§ì í this ê° ë° ì´ê¸° ì¸ì를 ì¬ì©íì¬ ë³ê²½í ì본 í¨ìì ë³µì 본.
ì¤ëª
bind() í¨ìë ìë¡ì´ ë°ì¸ë©í í¨ì를 ë§ëëë¤. ë°ì¸ë©í í¨ìë ì본 í¨ì ê°ì²´ë¥¼ ê°ì¸ë í¨ìë¡, ECMAScript 2015ìì ë§íë í¹ì´ í¨ì ê°ì²´(exotic function object)ì
ëë¤. ë°ì¸ë©í í¨ì를 í¸ì¶íë©´ ì¼ë°ì ì¼ë¡ ëíë í¨ìê° í¸ì¶ ë©ëë¤.
ë°ì¸ë©í í¨ìë ë¤ìê³¼ ê°ì ë´ë¶ ìì±ì ê°ì§ê³ ììµëë¤.
[[BoundTargetFunction]]- ë°ì¸ë©ì¼ë¡ ê°ì¼(wrapped) ì본 í¨ì ê°ì²´.[[BoundThis]]- ê°ì¸ì§ í¨ì를 í¸ì¶íì ë íì ì ë¬ëë ê°.[[BoundArguments]]- ê°ì¸ì§ í¨ìê° í¸ì¶ë ë 첫 ë²ì§¸ ì¸ìë¡ ì¬ì©ëë ê°ë¤ì 목ë¡.[[Call]]- ì´ ê°ì²´ì ê´ë ¨ë ì½ë ì¤í. í¨ì í¸ì¶ ìì íµí´ í¸ì¶ë¨. ë´ë¶ ë©ìëì ì¸ìë this ê° ë° í¸ì¶ ìì¼ë¡ í¨ìì ì ë¬ëë ì¸ì를 í¬í¨íë 목ë¡ì ëë¤.
ë°ì¸ë©ë í¨ìê° í¸ì¶ë ë [[BoundTargetFunction]]ì ë´ë¶ ë©ìë [[Call]]ì í¸ì¶í©ëë¤. [[Call]] ì Call(boundThis, args)ì ê°ì ì¸ì를 ê°ì§ëë¤. ì´ ë, boundThisë [[BoundThis]]ì´ê³ , argsë í¨ìê° í¸ì¶ë ë ì ë¬ëì´ ë°ë¼ì¤ë [[BoundArguments]] ì
ëë¤.
ë°ì¸ë©ë í¨ìë new ì°ì°ì를 ì¬ì©íì¬ ìì±ë ìë ììµëë¤: ê·¸ë ê² íë©´ ëì í¨ìê° ë§ì¹ ëì ìì±ë ê²ì²ë¼ íëí©ëë¤. ì ê³µë this ê°ì 무ìë©ëë¤, ìì ë¶ì¸(prepend) ì¸ìë ì뮬ë ì´í¸ë í¨ìì ì ê³µëì§ë§.
ìì
>ë°ì¸ë©ë í¨ì ìì±
bind()ì ê°ì¥ ê°ë¨í ì¬ì©ë²ì í¸ì¶ ë°©ë²ê³¼ ê´ê³ìì´ í¹ì this ê°ì¼ë¡ í¸ì¶ëë í¨ì를 ë§ëë ê²ëë¤. ì´ë³´ JavaScript íë¡ê·¸ë머ë¡ì íí ì¤ìë ê°ì²´ë¡ë¶í° ë©ìë를 ì¶ì¶í ë¤ ê·¸ í¨ì를 í¸ì¶í ë, ì본 ê°ì²´ê° ê·¸ í¨ìì thisë¡ ì¬ì©ë ê²ì´ë¼ 기ëíë ê²ëë¤(ìì : ì½ë°± ê¸°ë° ì½ëìì í´ë¹ ë©ìë ì¬ì©). ê·¸ë¬ë í¹ë³í ì¡°ì¹ê° ìì¼ë©´, ëë¶ë¶ì ê²½ì° ì본 ê°ì²´ë ìì¤ë©ëë¤. ì본 ê°ì²´ê° ë°ì¸ë© ëë í¨ì를 ìì±íë©´, ì´ë¬í 문ì 를 ê¹ëíê² í´ê²°í ì ììµëë¤.
this.x = 9;
var module = {
x: 81,
getX: function () {
return this.x;
},
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// 9 ë°í - í¨ìê° ì ì ì¤ì½íìì í¸ì¶ëì
// moduleê³¼ ë°ì¸ë©ë 'this'ê° ìë ìë¡ì´ í¨ì ìì±
// ì ì
íë¡ê·¸ë머ë ì ì ë³ì xì
// moduleì ìì± x를 í¼ëí ì ìì
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
ë¶ë¶ ì ì© í¨ì
bind()ì ë¤ìì¼ë¡ ê°ë¨í ì¬ì©ë²ì 미리 ì§ì ë ì´ê¸° ì¸ìê° ìë í¨ì를 ë§ëë ê²ëë¤. ì§ì ë ì´ê¸° ì¸ìê° ìë¤ë©´ ì ê³µë this ê°ì ë°ë¥´ê³ , ë°ì¸ë© ë í¨ìì ì ë¬ëì´ ë°ì¸ë© ë í¨ìê° í¸ì¶ë ëë§ë¤ ëì í¨ìì ì¸ì ìì ì½ì
ë©ëë¤.
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
// ì íë ì¸ì를 ì¤ì íì¬ í¨ì를 ìì±í©ëë¤.
var leadingThirtysevenList = list.bind(null, 37);
var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
function addArguments(arg1, arg2) {
return arg1 + arg2;
}
var result1 = addArguments(1, 2); // 3
// 첫 ë²ì§¸ ì¸ì를 ì§ì íì¬ í¨ì를 ìì±í©ëë¤.
var addThirtySeven = addArguments.bind(null, 37);
var result2 = addThirtySeven(5); // 37 + 5 = 42
// ë ë²ì§¸ ì¸ìë 무ìë©ëë¤.
var result3 = addThirtySeven(5, 10); // 37 + 5 = 42
setTimeoutê³¼ í¨ê» ì¬ì©
window.setTimeout() ë´ìì 기본ì¼ë¡, this í¤ìëë window (ëë global) ê°ì²´ë¡ ì¤ì ë©ëë¤. í´ëì¤ ì¸ì¤í´ì¤ë¥¼ 참조íë this를 íìë¡ íë í´ëì¤ ë©ìëë¡ ìì
íë ê²½ì°, ëª
ìí´ì this를 ì½ë°± í¨ìì ë°ì¸ë©í ì ììµëë¤, ì¸ì¤í´ì¤ë¥¼ ì ì§í기 ìí´.
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// 1ì´ ì§ì²´ í bloom ì ì¸
LateBloomer.prototype.bloom = function () {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function () {
console.log("I am a beautiful flower with " + this.petalCount + " petals!");
};
var flower = new LateBloomer();
flower.bloom();
// 1ì´ ë¤, 'declare' ë©ìë ì ë°
ìì±ìë¡ ì°ì´ë ë°ì¸ë©ë í¨ì
ê²½ê³ :
ì´ ë¶ë¶ì JavaScript ë¥ë ¥ì ë³´ì´ê³ bind() ë©ìëì ì¼ë¶ ê·¹ë¨ ìí©(edge case)ì 기ë¡í©ëë¤. ìë ë³´ì´ë ë©ìëë ì¼ì íë ê°ì¥ ì¢ì ë°©ë²ì ìëë©° ìë§ë ìì© íê²½ìì ì í ì¬ì©ëì§ ìì ê²ëë¤.
ë°ì¸ë©ë í¨ìë ìëì¼ë¡ ëì í¨ìì ìí´ ìì±ëë ìë¡ì´ ì¸ì¤í´ì¤ë¥¼ ìì±íë new ì°ì°ìì í¨ê» ì°ê¸°ì ì í©í©ëë¤. ë°ì¸ë©ë í¨ìê° ê°ì ìì±íë ë° ì°ì´ë ê²½ì°, ì ê³µë thisë 무ìë©ëë¤. ê·¸ë¬ë, ì ê³µë ì¸ìë ì¬ì í ìì±ì í¸ì¶ì (ì¸ìë¶) ìì ë¶ìµëë¤:
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return this.x + "," + this.y;
};
var p = new Point(1, 2);
p.toString(); // '1,2'
// ìë í´ë¦¬íììë ì§ìëì§ ìì,
// ì bindìë ì ìë:
var YAxisPoint = Point.bind(null, 0 /*x*/);
var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0 /*x*/);
var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'
axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true
newì í¨ê» ì°ê¸° ìí ë°ì¸ë©ë í¨ì를 ë§ë¤ê¸° ìí´ í¹ë³í ì¼ì í íìê° ììì 주ìíì¸ì. ê·¸ ê²°ê³¼ ë¶ëª
í í¸ì¶ëë ë°ì¸ë©ë í¨ì를 ë§ë¤ê¸° ìí´ í¹ë³í ì무ê²ë í íìê° ììµëë¤, ì¤íë ¤ new를 ì¬ì©í´ìë§ í¸ì¶ëë ë°ì¸ë©ë í¨ì를 ì구íë ê²½ì°ìë.
// ìë JavaScript ì½ììì ì§ì ì¤íë ì ìì
// ...ìììë¶í° ì´ì´ì§
// ì¬ì í ì¼ë° í¨ìë¡ì í¸ì¶ë ì ìì
// (ë³´íµ ì´ë¥¼ ìíì§ ìëë¼ë)
YAxisPoint(13);
emptyObj.x + "," + emptyObj.y;
// > '0,13'
ì¤ë¡ì§ new를 ì¬ì©íê±°ë í¸ì¶í´ìë§ ë°ì¸ë©ë í¨ìì ì¬ì©ì ì§ìíê³ ì¶ì ê²½ì°, ëì í¨ìë ê·¸ ì íì ê°ì í´ì¼ í©ëë¤.
ë°ë¡ ê°ê¸° ìì±
bind()ë í¹ì this ê°ì íìë¡ íë í¨ìì ë°ë¡ ê°ê¸°(shortcut)를 ë§ë¤ê³ ì¶ì ê²½ì°ìë ëìì´ ë©ëë¤.
ê°ë ¹, ë°°ì´ ê°ì ê°ì²´ë¥¼ ì¤ì ë°°ì´ë¡ ë³ííë ë° ì¬ì©íê³ ì¶ì Array.prototype.slice를 ì·¨íì¸ì. ì´ì ê°ì ë°ë¡ ê°ê¸°ë¥¼ ë§ë¤ ì ììµëë¤:
var slice = Array.prototype.slice;
// ...
slice.apply(arguments);
bind()ë¡, ì´ë ë¨ìíë ì ììµëë¤. ë¤ì ì¡°ê° ì½ëìì, sliceë Function.prototypeì apply() í¨ìì ë°ì¸ë©ë í¨ìì
ëë¤, this ê°ì Array.prototypeì slice() í¨ìë¡ ì¤ì í ì±. ì´ë ì¶ê° apply() í¸ì¶ì ìì ë ì ììì ë»í©ëë¤:
// ì´ì ììì "slice"ì ê°ì
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.apply.bind(unboundSlice);
// ...
slice(arguments);
í´ë¦¬í
bind í¨ìë ECMA-262 ì 5íì ì¶ê°ëììµëë¤; ê·¸ë¬í기ì 모ë ë¸ë¼ì°ì ì ìì ì ììµëë¤. ì¤í¬ë¦½í¸ ìì ë¶ë¶ì ë¤ì ì½ë를 ì½ì
í¨ì¼ë¡ì¨ ì´ ë¬¸ì 를 ë¶ë¶ì ì¼ë¡ í´ê²°í ì ìì¼ë©°, bind() ì§ìíì§ ìë 구íììë ëë¶ë¶ì 기ë¥ì ì¬ì©í ì ììµëë¤.
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// ECMAScript 5 ë´ë¶ IsCallable í¨ìì
// ê°ë¥í ê°ì¥ ê°ê¹ì´ ê²
throw new TypeError(
"Function.prototype.bind - what is trying to be bound is not callable",
);
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(
this instanceof fNOP ? this : oThis,
aArgs.concat(Array.prototype.slice.call(arguments)),
);
};
if (this.prototype) {
// Function.prototypeì prototype ìì±ì´ ìì
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
return fBound;
};
}
ì´ ìê³ ë¦¬ì¦ê³¼ ì¤ííë ìê³ ë¦¬ì¦ ê° ë§ì ì°¨ì´(ì¶©ë¶í ë¤ë¥¸ ì°¨ì´ê° ìì ì ììµëë¤, ì´ ëª©ë¡ì ì ë§ ì² ì í íì§ ìì기ì) ì¤ ì¼ë¶ë ë¤ìì ëë¤:
- ë¶ë¶ 구íì
Array.prototype.slice(),Array.prototype.concat(),Function.prototype.call()ë°Function.prototype.apply(), ìë ê°ì ê°ë ë´ì¥ ë©ìëì ìì¡´í©ëë¤. - ë¶ë¶ 구íì ë¶ë³(immutable) "poison pill"
callerë° get, set ëë ìì ìTypeErrorê° ë°ìíëargumentsìì±ì´ ìë í¨ì를 ë§ëëë¤. (ì´ë 구íì´Object.defineProperty를 ì§ìíë ê²½ì° ì¶ê° ëë 구íì´Object.prototype.__defineGetter__()ë°Object.prototype.__defineSetter__()ë©ìë를 ì§ìíë ê²½ì° [ìì ì ì¤ë¥ ë°ì(throw-on-delete) ëì(behavior) ìì´] ë¶ë¶ 구íë ì ììµëë¤.) - ë¶ë¶ 구íì
prototypeìì±ì´ ìë í¨ì를 ë§ëëë¤. (ê³ ì ë°ì¸ë©ë í¨ìë ììµëë¤.) - ë¶ë¶ 구íì
lengthìì±ì´ ECMA-262ì ìí´ ë¶ì¬ë(mandated) ê·¸ê²ê³¼ ì¼ì¹íì§ ìë ë°ì¸ë©ë í¨ì를 ë§ëëë¤: ê¸¸ì´ 0ì¸ í¨ì를 ë§ëëë¤, ë°ë©´ì ì ì²´ 구íì ëì í¨ìì ê¸¸ì´ ë° ë¯¸ë¦¬ ì§ì ë ì¸ìì ìì ë°ë¼ 0ì´ ìë 길ì´ë¥¼ ë°íí ì ììµëë¤.
ì´ ë¶ë¶ 구íì ì°ê¸°ë¡ ê³ ë¥¸ ê²½ì°, ëìì´ ECMA-262 ì 5íì ë²ì´ë ê²½ì°ì ìì¡´íì§ ììì¼ í©ëë¤! ê·¸ë¬ë 주ì ì½ê°(ê³¼ ìë§ë í¹ì ì구ì ë§ì¶ê¸° ìí ì¶ê° ìì )ì¼ë¡, ì´ ë¶ë¶ 구íì bind()ê° ì¤íì ë°ë¼ ë리 구íë ëê¹ì§ ì ë¹í ë¤ë¦¬ê° ë ì ììµëë¤.
ëª ì¸ì
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-function.prototype.bind> |