본문 바로가기

Programing/JavaScript

[JavaScript] Function Methods, Prototype

아래 코드를 직접 실행해보세요


1
2
3
4
5
6
var arr = [1234];
arr.isArray();  // does it works?
 
Array.map(function(current, index) {
    return current;
});  // does it works?
cs


그렇다면 왜 Object.prototype.something와 같이 설명되어 있을까요?

prototype은 무엇을 의미하나요 ?


MEANING OF PROTOTYPE

· 인스턴스가 생성(instantiation)될 때 원형(original form), 즉 프로토타입(prototype)의 모양대로 인스턴스가 생성

· 인스턴스의 메소드는 Object.prototype.someting으로 표현


prototype === 원형

비유하자면 prototype은 붕어빵틀, instance는 빵틀에서 나오는 붕어빵들




HOW ABOUT class? 

· JavaScript는 prototype 기반 언어

· prototype을 기반으로 객체지향 프로그래밍(OOP)를 흉내냄

· 문법적인 편의로 class란 keyword를 도입(ES6)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Car(brand) {
    this.brand = brand;
}
 
var avante = new Car('avante');
avante  // Car { brand : 'avante' };
 
var benz = new Car('benz');
benz  // Car { brand : 'benz' }
 
Car.prototype.ride = function() {
    console.log(this.brand + ' is riding' );
}  // ride라는 메소드를 만들어준것
 
avante.ride()  // avante is riding
benz.ride()  // benz is riding
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Car {
    constructor(brand) {
        this.brand = brand;
    }
 
    ride() {
        console.log(this.brand + ' is riding');
    }  // 바로 만들어줄 수도 있다.
}
 
var avante = new Car('avante');
var benz = new Car('benz');
 
avante.ride()  // avante is riding
benz.ride()  // benz is riding
cs




EXTENDING PROTOTYPE

· JavaScript에서 기본적으로 제공되는 객체에 사용자 정의 메소드를 직접 추가할 수 있음(그러나, 추천하지않음)

· 메소드 확장은, 다른코드와 충돌을 일으킬 수 있음


1
2
3
4
5
6
Number.prototype.invert = function() {
    return -(this)    // this는 num num = 5니까 this 5
}
 
var num = 5;
num.invert();  // -5
cs


직접 객체(클래스)를 작성할 때, 프로토타입 메소드를 사용하세요




Function prototype methods

- Function.prototype.call

    - function.call(thisArg, arg1, arg2, ...)

- Function.prototype.apply

    - function.apply(thisArg, [argArray])




.call or .apply invocation

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
    string: 'origin',
    foo: function() {
        console.log(this.string);
    }
};
 
var obj2 = {
    string: 'what?'
};
 
obj.foo();  // 'origin'
obj.foo.call(obj2);  // 'what?'
cs




Using .call in action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function foo() {
    console.log(arguments);
}
 
foo('a''b');
/* arguments는
0: 'a'
1: 'b'
이렇게 나오지만, 배열은 아니다. 비슷한 형식일뿐 */
 
Array.prototype.slice.call([123], 1)
// [2, 3] 이런 형식은 가능
[123].slice(1)
// [2, 3] Array.prototype.slice.call([1, 2, 3], 1)와 같다.
 
var arr = ['code'];
Array.prototype.push.call(arr, 'states''hello');
arr;  // ['code', 'states', 'hello']
 
function foo() {
    return Array.prototype.slice.call(arguments);
}
 
foo('a''b');
//['a', 'b']  => array형태임
 
function makeParamsToArray() {
    return Array.prototype.slice.call(arguments);
}
 
console.log(makeParamsToArray('code''states'));
// ['code', 'states']
cs



★★★★★★★

1
2
3
4
5
6
7
8
9
10
11
12
// same as Math.max([value1[, value2[, ...]]])
// Math.max(1, 2, 3, 4, 5) === 5
 
function getMax() {
    var argsArray = Array.prototype.slice.call(arguments);
    var maxValue = argsArray.reduce(function(accumulator, currentValue)
        return (accumulator > currentValur) ? accumulator : currentValue;
    });
    return maxValue;
}
 
console.log(getMax(45273));
cs


1
2
var arr = [12357442];
Math.max.apply(null, arr);  // 74
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function Product(name, price) {
    this.name = name;
    this.price = price;
    this.print = function() {
        console.log(this.constructor.name + ': ' + this.name + '\t\t' + this.price + 'USD');
    }
}
 
function Food(name, price) {
    Product.call(this, name, price);  // === Product.apply(this, arguments);  ??
    this.category = 'food';
}
 
function Toy(name, price) {
    Product.call(this, name, price);
    this.category = 'toy';
}
 
var cheese = new Food('feta''5);
var fun = new Toy('robot', 40);
cheese.print();
fun.print();
cs


→ 이거 왜 실행안되지




Function prototype methods

- Function.prototype.bind

· 인자로 넘겨준 객체와 연결(bind)된 새로운 함수를 반환

· callback 함수를 특정 객체와 연결하고 싶을 때 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Box(w, h) {
    this.width = w;
    this.height = h;
 
    this.getArea = function() {
        return this.width * this.height;
    }
 
    this.printArea = function() {
        console.log(this.getArea());
    }
 
    this.printArea();
    setTimeout(this.printArea, 2000);  // printArea를 2초후 실행
    // 이렇게 쓰면 실행안됨 왜냐면 setTimeout은 기본적으로 window를 연결시키기 때문
    // 이 문제를 해결하기 위해서는 bind를 사용하면됨
    // => setTimeout(this.printArea.bind(this), 2000);
 
}
 
var b = new Box(10050);
cs




setTimeout ? 

1
2
3
4
5
6
7
setTimeout(function() {
    console.log('2초후에 실행');
}, 2000);  // 2초후에 실행됨
 
setTimeout(function() {
    console.log('5초후에 실행');
}, 5000);  //5초후에 실행됨
cs


bind : this를 명시적으로 표현하기위해 씀, 바로 실행되지않음


1
2
3
4
5
6
7
8
9
function template(name, money) {
    return '<h1>' + name + '</h1><span>' + money + '</span>';
}
 
var tmplIngi = template.bind(null'Ingi Kim');
var tmplHoyong =  template.bind(null'Hoyong Lee');
 
tmplIngi(5000);
  // "<h1>Ingi Kim</h1><span>5000</span>"
cs








'Programing > JavaScript' 카테고리의 다른 글

[JavaScript] 랜덤하게 문자 만들기  (0) 2019.02.27
[JavaScript] hasOwnProperty()  (0) 2019.02.27
[JavaScript] this / call, apply 호출  (0) 2019.02.14
[JavaScript] Closure  (0) 2019.02.13
[JavaScript] Scope  (0) 2019.02.13