# 목차
* call() 정의
* call()을 생성자 연결에 사용
* call()을 익명함수와 함께 쓰기
* call()호출시 첫번째 인자값에 특정 값을 넣어 동작하기
* call()호출시 첫번째 인자값 넣지 않고 동작하기
* call, apply함수의 비교(this에 특정 값 넣어 동작)
* bind()
* bind()함수 구현 해보기
* creating a bound function
* Partially applied functions
* with setTimeout()call() 정의
주어진 this 값, 전달된 인수 와 함께 함수를 호출
function Product(name, price) {
this.name = name
this.price = price
}
function Food(name, price) {
Product.call(this, name, price)
this.category = "food"
}
console.log(new Food("cheese", 5).name)
// expected output: "cheese"call()을 생성자 연결에 사용
function, method에 속해서 다른 객체를 호출한다.
function, method에 this 값을 전해준다.
함수는 한번 쓰고 다른 객체에서 상속 받아 사용한다.(method를 다시 만들 필요 없이)
function Product(name, price) {
this.name = name
this.price = price
if (price < 0) {
throw RangeError(
"Cannot create product " + this.name + " with a negative price"
)
}
}
function Food(name, price) {
Product.call(this, name, price) //Product function을 재사용
this.category = "food"
}
function Toy(name, price) {
Product.call(this, name, price) //Product function을 재사용
this.category = "toy"
}
var cheese = new Food("feta", 5)
var fun = new Toy("robot", 40)call()을 익명함수와 함께 쓰기
var animals = [
{ species: "Lion", name: "King" },
{ species: "Whale", name: "Fail" },
]
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log("#" + i + " " + this.species + ": " + this.name)
}
this.print()
}.call(animals[i], i))
}
//## 결과
//#0 Lion: Kinf
//#1 Whale: Failcall()호출시 첫번째 인자값에 특정 값을 넣어 동작하기
function greet() {
var reply = [this.animal, "typically sleep between", this.sleepDuration].join("")
console.log(reply)
}
var obj = {
animal: "cats",
sleepDuration: "12 and 16 hours",
}
greet.call(obj) // cats typically sleep between 12 and 16 hourscall()호출시 첫번째 인자값 넣지 않고 동작하기
call로 호출될 function 안에 this의 bound는 global object이다
하지만 use stric을 사용 하용하면 undefined가 나온다.
var sData = "Wisen"
function display() {
console.log("sData value is %s ", this.sData)
}
display.call() // sData value is Wisen"use strict"
var sData = "Wisen"
function display() {
console.log("sData value is %s ", this.sData)
}
display.call() // Cannot read the property of 'sData' of undefinedcall, apply함수의 비교(this에 특정 값 넣어 동작)
var obj = { name: "Jaeyoon" }
var greeting = function(a, b) {
return "welcome to " + a + " in " + b + " " + this.name
}
console.log(greeting.call(obj, "Korea", "Seoul"))
//welcome to Korea in Seoul Jaeyoon
var obj = { name: "Jaeyoon" }
var greeting = function(a, b) {
return "welcome to " + a + " in " + b + " " + this.name
}
console.log(greeting.apply(obj, ["Korea", "Seoul"]))
//welcome to Korea in Seoul Jaeyoonbind()
함수와 객체를 서로 묶는 것이다.
bind()함수는 새 함수를 반환한다.(call, apply는 바로 동작)
function f(arg1, arg2) {
return (this.x * arg1) + arg2
} //바인드되어야 하는 함수
var o = { x: 1 } //바인드될 객체
var g = f.bind(o, 10) //g(x)를 호출하면 o.f(x)가 호출된다.
g(5) //=>15bind()함수 구현 해보기
Function.prototype.bind = function(obj){
//this와 인자 값을 변수에 저장함으로써 다음의 중첩 함수에서 사용할 수 있다.
var me = this, boundArgs = arguments;
//bind() 메서드의 반환 값은 함수다.
return function(){
//인자 목록을 작성하는데, 첫 번재 이후의 인자부터
//나머지 모든 인자를 이 함수에 전달 한다.
var args = [], i;
// POINT: i가 1부터 시작하는 이유는 bind함수 두번째부터 인자값을 설정 할 수 있기 때문
for(i = 1; i < boundArgs.length; i++) args.push(boundArgs[i]);
for(i = 0; i < arguments.length; i++) args.push(arguments[i]);
//인자들을 포함하여 obj의 메서드로 me를 호출한다.
// POINT - obj: outer함수의 clousre 영역에 있는 변수
return me.apply(obj, args);
}
}creating a bound function
this.x = 9 // this refers to global "window" object here in the browser
var module = {
x: 81,
getX: function() {
return this.x
},
}
var retrieveX = module.getX
module.getX() // return: 81 - The ufnction gets invoked at the module scope
retrieveX() // returns 9 - The function gets invoked at the global scope
// Create a new function with 'this' bound to module
// New programmers might confuse the global var x with module's property x
var boundGetX = retrieveX.bind(module)
boundGetX() // 81Partially applied functions
function list() {
return Array.prototype.slice.call(arguments)
}
function addArguments(arg1, arg2) {
return arg1 + arg2
}
var list1 = list(1, 2, 3) // [1, 2, 3]
var result1 = addArguments(1, 2) // 3
// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(null, 37)
var list2 = leadingThirtysevenList() // [37]
var list3 = leadingThirtysevenList(1, 2, 3) // [37, 1, 2, 3]
// Create a function with a preset first argument.
var addThirtySeven = addArguments.bind(null, 37)
var result2 = addThirtySeven(5) // 37 + 5 = 42
var result3 = addThirtySeven(5, 10) // 37 + 5 = 42 , second argument is ignoredwith setTimeout()
function LateBloomer() {
this.petalCount = Math.floor(Math.random() * 12) + 1
}
// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
// #POINT
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()
// after 1 second, triggers the 'declare' method