Data structures and types
Data types- Boolean
- null
- undefined
- Number
- String
- Symbol
- Object
Primitive wrapper objects
원시타입형에서 properties에 값을 할당은 안되지만, 오류는 아닙니다. 이는 null과 undefined를 제외한, 나머지 원시값은 그 값들을 감싸는 primitive wrapper objects 때문입니다. 객체의 원시값을 가져올때는 valueOf() 사용가능합니다.
var fred = "Fred Flintstone";
fred.favoriteFood = "Brontosaurus Steak";
// Outputs: undefined
console.log(fred.favoriteFood);
// 문자열 표현
let str1 = new String('str1')
let str2 = 'str2'
typeof str1 // 'object'
typeof str2 // 'string'
str1 instanceof String // true
str2 instanceof String // false
str1 instanceof Object // true
str2 instanceof Object // false
NaN
typeof NaN === 'number' // true
NaN === NaN // false
NaN !== NaN // true
isNaN(NaN) // true
isNaN(0) // false
isNaN('oops') // true
isNaN('0') // false
// 숫자 구별방법
function isNumber(value) {
return typeof value === 'number' && isFinite(value);
}
Literals Array, Boolean, Floating-point, Integers, Object, RegExp, String
var coffees = ['French Roast', 'Colombian', 'Kona'];
var cats = [];
cats[30] = ['Dusty'];
console.log(cats.length); // 31
console.log(cats['length']); // 31
배열의 length를 이용하여 값을 제거할 수 있습니다.
var cats = ['Dusty', 'Misty', 'Twiggy'];
console.log(cats.length); // 3
cats.length = 2;
console.log(cats);
for 문과 forEach()를 사용해서 배열을 순환할 수 있습니다.
var colors = ['red', 'green', 'blue'];
for (var i = 0; i < colors.length; i++) {
console.log(colors[i]);
}
var colors = ['red', 'green', 'blue'];
colors.forEach(color => console.log(color));
Array methods
아래 배열 매소드 중에서 자주 사용하는 것으로는concat()-new, join(), push(), pop(), shift(), unshift(), slice()-new, splice(), sort(), indexOf(), lastIndexOf(), forEach(), map()-new, filter()-new, every()-true/false, some()-true/false, reduce(), reduceRight() 특정값이 있는지 찾을때는 indexOf()를 사용합니다. 매칭되는 첫 번째 포지션을 리턴하며 없을 경우 -1 을 리턴합니다.
var isExist = (array.indexOf(“특정값”)!== -1 )
filter를 사용해서 JSON 오브젝트로 이루어진 배열중에 특정 값만 필터 시킬때 사용합니다.
var arr = [
{"name":"apple", "count": 2},
{"name":"orange", "count": 5},
{"name":"pear", "count": 3},
{"name":"orange", "count": 16}
];
var newArr = arr.filter(function(item){
return item.name === "orange";
});
console.log("Filter results:",newArr);
for 루프대신 forEach()사용도 가능합니다.
var array = [1,2,3,4,5];
array.forEach( function( v, i ){
if( v === 3 ){
console.log( v + ":" + i); // 3:2 가 나온다.
}
});
map은 루프에서 return 할 수 있다는 특징과 길이가 같은 배열로 결과를 리턴받고 싶을 때 사용합니다.
reduce는 array를 하나의 값으로 리턴합니다.
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
배열은 정규표현식과 match의 결과값이기도 합니다.RegExp.exec(), String.match(), and String.split().
유사배열 객체 (array-like objects)
document.querySelectorAll(), document.getElementsByTagName()의 리턴값인 NodeList 또는 arguments는 배열처럼 생겼지만 모든 메소드를 사용할 수는 없습니다. 예를들어, arguments 객체는 length 속성을 제공하지만 forEach()를 사용할 수 없습니다. NodeList는 live collection 또는 static collection 입니다.
getElementsByClassName() : HTMLCollection & live
getElementsByTagName() : HTMLCollection & live
getElementsByName() : NodeList & live
querySelectorAll() : NodeList & not live
Iterators
iterable 프로토콜은 반복문을 가능케합니다. String, Array, TypedArray, Map, Set은 iterable이 내재되어 있습니다. @@iterator 메소드가 반드시 필요합니다. 객체에 iterator을 주입시키는 방법은 아래와 같습니다.
var myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...myIterable]; // [1, 2, 3]
for...of / for...in
for...in 은 객체의 enumerable 속성을 반복하며, for...of는 iterable 객체를 반복합니다. 첫번째 반복문에서는 0, 1, 2, "foo", "arrCustom", "objCustom"만 출력합니다. 배열안의 값인 3, 5, 7은 enumerable 속성이 아니기 때문입니다. 배열이 인덱스는 enumerable속성입니다.
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
enumerable은 간단히 말해 for...in 또는 Object.keys로 접근시 노출되는 것을 의미합니다. 아래 코드 실행시 enumerable의 값이 true로 나와 있습니다. 새로운 프로퍼티 생성시 이 값은 기본적으로 true로 설정되어 있기 때문입니다.
const obj = {
purposeOfLife: 42,
}
Object.getOwnPropertyDescriptor(obj, 'purposeOfLife')
// result
{
value: 42,
writable: true,
enumerable: true,
configurable: true
}
defineProperty를 사용할 때 주의 할점은 기본값이 false입니다. non-enumerable properties를 생성하려면 Object.definedProperty()를 사용하시면 됩니다.
var person = { age: 18 };
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false });
person.name; // 'Joshua'
Object.keys(person); // ['age']
Functions
자바스크립트에서 함수는 First-Class-Object로 변수나 데이터 구조안에 담을 수 있으며 인자로 전달할 수 있고 반환값으로도 사용할 수 있습니다. 원시형타입과 달리 함수의 파라미터에 배열 또는 객체를 넘겨서 함수 안에서 값을 변경할 경우 기존의 값이 바뀝니다.
function myFunc(theObject) {
theObject.make = 'Toyota';
}
var mycar = {make: 'Honda', model: 'Accord', year: 1998};
var x, y;
x = mycar.make; // x gets the value "Honda"
myFunc(mycar);
y = mycar.make;
함수선언(function declarations)이 위의 예제와 같다면 함수 표현식(function expressions)은 아래와 같습니다. 함수 표현식을 사용할 경우, 익명함수로 작성이 가능합니다. 자기호출함수로 해석과 동시에 실행되는 코드블럭 생성이 가능하며 이는 재귀함수와는 다른 개념입니다.
var square = function(number) { return number * number; };
var x = square(4); // x gets the value 16
//named function expression
var foo = function foo() {
console.log('hello');
};
// self invoking function expression
(function foo() {
console.log('hello');
})();
함수 표현식은 호이스팅 되지않습니다.
a();
b();
function a(str){
alert(str);
}
var b = function(str){
alert(str);
}
함수 스코프 안에 선언된 변수는 함수 밖에서 접근이 불가능합니다. 이유는 함수 스코프 안에서만 변수가 선언되기 때문입니다. 글로벌 스코프에 선언된 함수는 글로벌 변수 모두에 접근이 가능합니다. 함수 안에 선언된 자식 함수는 부모 함수가 접근 가능한 변수에 모두 접근이 가능합니다. 다른 함수에서 또 다른 함수 내부 변수에 접근하기 위해서는 글로벌 선언, 객체생성, 또는 파라미터로 전달하는 방법이 있습니다.재귀함수(recursive function )
자기 자신을 호출하는 함수를 재귀함수라고 합니다. 아래 while() 구문을 재귀함수로 대체 가능합니다.
var x = 0;
while (x < 10) { // "x < 10" is the loop condition
// do stuff
x++;
}
function loop(x) {
if (x >= 10) // "x >= 10" is the exit condition (equivalent to "!(x < 10)")
return;
// do stuff
loop(x + 1); // the recursive call
}
loop(0);
클로저 내부 함수는 외부 함수에 선언되어 있는 변수나 함수 값에 접근이 가능합니다.
var pet = function(name) { // The outer function defines a variable called "name"
var getName = function() {
return name; // The inner function has access to the "name" variable of the outer function
}
return getName; // Return the inner function, thereby exposing it to outer scopes
}
myPet = pet('Vivie');
myPet();
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex === 'string' && (newSex.toLowerCase() === 'male' || newSex.toLowerCase() === 'female')) {
sex = newSex;
}
}
}
}
var pet = createPet('Vivie');
pet.getName(); // Vivie
pet.setName('Oliver');
pet.setSex('male');
pet.getSex(); // male
pet.getName(); // Oliver
arguments객체 함수의 argument는 유사배열로 관리가 됩니다. 유사배열은 인덱스와 길이가 있지만, 배열의 모든 메소드를 사용할 수는 없습니다. 전달되는 arguments는 아래와 같은 형태를 가지고 있습니다. i값은 0부터 시작되며 전체 숫자는 arguments.length로 알 수 있습니다.
arguments[i]
함수 파라미터 함수 파라미터는 두 가지 종류가 있습니다. 하나는 default 이며 나머지 하나는 rest 파라미터 입니다. 자바스크립트 함수에서 default는 undefined입니다. 하지만 기본값을 설정하면 NaN대신 원하는 결과값이 출력됩니다.
function multiply(a, b) {
return a * b;
}
multiply(5);
NaN
function multiply(a, b = 1) {
return a * b;
}
multiply(5);
5
rest 파라미터 문법은 arguments 의 값들을 배열로 반환합니다.
function multiply(multiplier, ...theArgs) {
return theArgs.map(x => multiplier * x);
}
var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]
화살표 함수화살표 함수는 코드를 획기적으로 줄어줍니다. 화살표 함수를 사용하면 function과 return 을 생략할 수 있습니다.
var a = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
var a2 = a.map(function(s) { return s.length; });
console.log(a2); // logs [8, 6, 7, 9]
var a3 = a.map(s => s.length);
console.log(a3); // logs [8, 6, 7, 9]
또한, this 연결을 예상한대로 할 수 있습니다.
// 기존
function Person() {
var self = this; // Some choose `that` instead of `self`.
// Choose one and be consistent.
self.age = 0;
setInterval(function growUp() {
// The callback refers to the `self` variable of which
// the value is the expected object.
self.age++;
}, 1000);
}
// 개선
function Person() {
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
Comments
Post a Comment