아래 코드를 직접 실행해보세요
1 2 3 4 5 6 | var arr = [1, 2, 3, 4]; 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([1, 2, 3], 1) // [2, 3] 이런 형식은 가능 [1, 2, 3].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(4, 5, 2, 7, 3)); | cs |
1 2 | var arr = [1, 2, 3, 5, 74, 4, 2]; 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(100, 50); | 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 |