티스토리 뷰

Front-end

[Front-end] Javascript 기초 - 1

코헴 2019. 1. 28. 15:39

Javascript 기초 - 1

배열

length

var arr = [1,2,3,4];
arr.length; // 4

배열 길이를 알려줌

join

var arr = [1,2,3];
arr.join(); // "1,2,3" (default)
arr.join(':'); // "1:2:3"

concat

var arr = [1,2,3];
arr = arr.concat(4,5);  // [1,2,3,4,5]
arr.concat([6,7]);   // [1,2,3,4,5,6,7]

reverse

var arr = [1,2,3,4];
arr.reverse();   // [4,3,2,1]

push, pop

var arr = [1,2,3];
arr.push(4);   // 4
arr; // [1,2,3,4]
arr.pop();  // 4

unshift, shift

var arr = [1,2,3];
arr.unshift(0); //4
arr;  //[0,1,2,3]
arr.shift();     //[0]

배열의 앞에 추가하거나 뺀다. 기존의 배열이 변한다. 마찬가지로 unshift는 변한 배열의 길이를, shift는 shift된 항목을 반환한다.

splice(시작점, 지울 갯수, 넣을 것)

var arr = [1,2,3,4];
arr.splice(2,1,5);  //3
arr;  // [1,2,5,4];

map(function(값, 자릿수){조건}), 배열,forEach(function(값, 자릿수){ 조건 })

var arr = [1,2,3];
arr.map(function(x){
 return x+1;
}) // [2,3,4]
arr.forEach(function(x,i){
 alert(x + ':' + i);
});

배열의 항목들을 반복하면서 조작하는 함수. map과 forEach의 매개변수로 함수가 들어가는데 함수 안에 배열의 항목들은 어떻게 조작할 지 적어주면 됩니다. 예시에서는 각각 1을 더하는 것과 alert를 하는 조작을 했습니다. map과 forEach의 차이점은 map은 바뀐 새 배열을 반환하지만 forEach는 반환하지 않습니다. 따라서 forEach보다는 map이 활용성이 더 높습니다.

reduce(function(이전값, 현재){조건}), 배열 reduceRight

var arr = [1,2,3,4,5];
arr.reduce(function(prev, cur){
 return prev + cur;
}); // 15

배열을 왼쪽부터 조건을 적용해 하나의 값으로 만든다. 위의 코드의 조건은 이전 값과 현재 값을 더한 값을 반환하는거. 왼쪽 두개부터 시작하고, 이전값이 1이고 현재값은 2라서 더하면 3이된다. 이것은 다시 이전값이되고 이전값이 3, 현재값이 3이 되어서 더하면6 이것이 다시 이전값, 현재값4가 되어 10 마지막으로 이전값이 10이고 현재값은 5이면 값은 15이며, 최종결과를 반환하게 되어 15 반환.

filter(function(항목){ 조건})

var arr  = [5,2,3,4,1];
arr.sort(function(x,y){
 return x-y;
}); // [1,2,3,4,5];

indexOf, lastIndexOf

배열에 해당 값이 있는지 조사. 처음으로 찾은 위치를 반환하며, last의 경우 뒤에서부터 찾음

every(function(항목){ 조건 }), some(function(항목){ 조건 })

var arr = [1,3,5,7,9];
arr.every(function(i) {
 return i % 2 === 1;
}); //true

arr.every(function(i){
 return i<9;
}); //false

arr.some(function(i){
 return i ===9;
}); //true

각각 배열의 모든 항목 또는 일부 항목이 true 면 true를 반환.

즉 every는 모든 항목이 조건을 만족하면 true, some은 하나의 항목이라도 조건을 만족하면 true를 반환

isArray(값)

Array.isArray('array?'); // false
Array.isArray(['array?']) //true

Window 객체

사실 window는 모든 객체의 조상입니다. 전역객체(글로벌객체)라고 하는데요. 모든 객체를 다 포함하고 있기 때문에 window는 그냥 생략가능합니다. 그래서 그냥 parseInt 이렇게 할 수 있는겁니다. 프로그래밍에서 모든 건 다 이유가 있어요~! window 객체 아래를 보면, String, Boolean, Object, Number, Function, Array같은 자료형도 다 들어있습니다.

놀라운 것은 여러분이 만들었던 변수들(함수 안에서 선언한 변수 제외)도 모두 window 객체 안에 등록됩니다! 진짜인지 물어보죠.

var really = 'Really?'
window.really; // 'Really?'

진짜라네요. ^^ 이런 것들을 전역변수라고 합니다. 어디에서나 쓸 수 있는 애들이거든요. 반대로 함수 안에서 선언한 변수(지역변수)들은 그 함수 안에서만 쓸 수 있습니다.

이제 window 객체의 대표적인 메소드와 속성 몇 개만 알아봅시다.

open()

새창을 여는 데 사용. 팝업 창의 형태로 열 수도 있고, 새 탭으로도 열 수 있다. 첫번째 인자로 주소를 받고 두번째 인자로 새 탭으로 열지, 현재 탭에서 열지 설정할 수 있다. 세번째 인자로 새창에 대한 각종 설정을 전달할 수 있다.

open('https://naver.com'); //새 탭
open('http://naver.com', '_self'); //현재 탭
open('', '', 'width=200, height=200'); //가로세로 200px의 팝업창

document.write로 새 창의 내용을 변경할수도 있다.

var popup = window.open('', '', 'width=200, height=200');
popup.document.write('안녕하세요');

팝업창에서 원래 탭에 접근할 수도 있다. opener객체를 사용하면 된다.

popup.opener.document.write('hello');

encodeURI(), decodeURI()

encodeURI : 한글 -> 외계어

decodeURI : 외계어 -> 한글

setTimeout(함수, 밀리초), setInterval(함수, 밀리초)

setTimeout은 지정한 초 뒤에 실행되고, setInterval은 지정한 초마다 반복된다.

setTimeout(function(){
 alert('1초 뒤');
}, 1000);

setInterval(function() {
 console.log('1초 마다');
}, 1000)

clearTimeout, clearInterval

setTimeout, clearInterval 을 중간에 멈추고 싶을 경우 사용

아래와같이 setTimeout(setInterval)을 변수에 저장해놓은 후 사용.

var timeout = setTimeout(function() {}, 1000);
clearTimeout(timeout);

getComputedStyle

알아두면 유용한 태그의 스타일을 찾는 메소드이다. 현재 적용된 CSS 속성 값을 알 수 있어서 유용하다.

console.log(getComputedStyle(document.getElementById('app-root')));

BOM

navigator

브라우저나 운영체제에 대한 정보가 있습니다.(navigator.userAgent);

navigator.language; //ko
navigator.cookieEnabled; //true
navigator.vendor; //Google Inc

screen

화면에 대한 정보를 알려준다. 너비, 높이, 픽셀, 컬러, 호면 방향, 작업표시줄을 제외한 너비와 높이 등이 있다. 화면 크기에 따라 다른 동작을 하고 싶을때 사용한다.

screen.availHeight;
screen.availWidth;
screen.colorDepth;

location

location 객체는 주소에 대한 정보를 알려준다.

location.host; // "www.naver.com"
location.hostname; // "www.naver.com"
location.protocol; // "https:"
location.href; // "https://www.naver.com/~~"
location.pathname; // "/category/Javascript~~"

history

history는 앞으로가기(history.forward() or history.go(1)), 뒤로가기(history.back() or history.go(-1))같은 것을 관장한다. 히스토리간에 이동(history.go(페이지수))할수도 있습니다. history.length는 뒤로가기할수 있는 페이지의 개수를 의미합니다.

history.pushState(객체, 제목, 주소)와 history.replaceState(객체, 제목, 주소) 는 HTML5에 추가되었는데, 페이지를 이동하지 않고 단순히 주소만 바꿔준다. 대신 객체 부분에 페이지에 대한 정보를 추가할 수 있다. 이것은 단일 페이지 어플리케이션을 만들 때 자주 이용되는데, 페이지 깜빡임 없이 주소를 바꾸고, 바뀐 주소에 따른 액션을 위할 때 사용한다.

document

document는 웹페이지를 담당하는 객체.(html 에 관한 것들을 담당하는) 때문에 대부분의 것들이 태그를 선택하고 조작하는데 사용된다.

document.getElementById(아이디)

html에서 해당 아이디를 가진 태그를 선택한다.

document.getElementById('app-root');

document.getElemenetsByClassName(클래스), document.getElementsByName(이름), document.getElementsByTagName(태그)

html에서 각각 해당 클래스, 네임, 태그명을 가진 태그를 선택한다. 여러개 선택되기 때문에 항상 배열이다. 메소드 이름도 elements이다.

document.querySelector(선택자), document.querySelectorAll(선택자)

css 선택자로 선택할 수 있게 해준다. 아이디는 #, 클래스는 . 태그명[속성명=속성값] 같은 것도 할 수 있고, 부모>자식, 부모 자손 등등 css의 선택자는 거의 다 쓸 수 있다.

document.querySelector('#app-root');

document.createElement(태그명)

document에 새로운 태그를 만들 때 사용한다. 만든다고 바로 생기는게 아니라 변수를 통해 메모리에 저장된다. 만든 태그를 추가하는 메소드는 따로 있다.

var div = document.createElement('div');

document.createTextNode(텍스트);

텍스트도 하나의 요소이다. 텍스트를 따로 만들 수 있다. 여기서 Node는 태그와 텍스트를 가르키는 명칭이다. 역시 바로 생기는게 아니라 변수를 통해 메모리에 저장된다.

var text = docuemnt.createTextNode('텍스트');

document.createDocumentFragment()

가짜 document를 만든다. 이것이 중요한 이유는 자바스크립트로 document의 태그를 조작하는 것은 매우 성능이 떨어진다. 특히 여러 태그를 반복문을 통해 동시에 추가할 때에 그렇다. 이럴때 미리 가짜 doucment를 만들어서 여기에 추가를 한 후, 한번에 document에 추가를 하게 되면 진짜 document는 한번만 조작하면 되기 때문에 성능에 부담이 덜한다.

간단한 예시를 살펴보면 다음과 같다 (appendChild 메소드가 위에 말한 dom을 추가하는 코드)

var div = document.createElement('div');
var text = document.createTextNode('텍스트');
var fragment = document.createDocumentFragment();
div.appendChild(text);
fragment.appendChild(div);
document.body.appendChild(fragment);

document.head, document.body

각각 html의 헤드와 body에 접근할 수 있게 해준다.

document.anchors, document.links, document.forms, document.images, document.scripts

이름처럼 각각 모든 html 앵커, 링크, 폼, 이미지, 스크립트에 접근할 수 있게 해준다.

document.title

문서의 제목에 접근 가능하다.

DOM

DOM이란 Document Object Model을 일컫는다. document를 객체로 구현했다고 생각하면 된다.

html은 계층적 구조로 되어있는데, Header, main, footer, script의 부모는 body 이고 head와 body의 부모는 html 이라고 할 수 있다. head와 body는 형제자매 관계인것이다. header는 body의 자식이고, footer의 안에는 태그 대신 hello 라는 문자가 들어있다. 전 시간에 다룬 텍스트 노드를 말한다.

이러한 것들을 객체로 표현할 수 있는데, 다음과 같다

{
 document : {
   html : {
     head: {
       title: ...
    },
     body : {
       header: ...
    }
  }
}
}

위와 같이 만든것이 DOM이다.

Node와 Element

Node와 Element에 대해 알아보자. Node는 태그 노드와 텍스트 노드 전체를 가르키고, Element는 텍스트 노드를 제외하고 흔히 생각하는 태그만 가르킨다. 따라서 태그만 검색하고 싶을 땐 Element가 붙은 메소드를 선택해야 한다. 아래는 자주 쓰이는 DOM의 속성이다.

속성

태그.nodeType

일단 태그를 선택한 후 nodeType 속성을 검색하면 해당 태그의 종류를 알려주는 숫자가 나온다.

  • 1 (Node.ELEMENT_NODE) -> Element

  • 3 (Node.TEXT_NODE) -> 텍스트

  • 8 (Node.COMMENT_NODE) -> 주석

  • 9 (Node.DOCUMENT_NODE) -> Document

  • 10 (Node.DOCUMENT_TYPE_NODE) -> DOCTYPE

  • 11 (Node.DOCUMENT_FRAGMENT_NODE) -> Document Fragment

태그.children, 태그.childNodes

자식으로 갈 때는 children(텍스트 노드 제외) 또는 childNodes(텍스트 노드 포함) 를 사용합니다.

document.body.children; // [header, main, footer, script]

따라서 main을 선택하고 싶다면 document.body.children[1]을 선택하면 된다.

이 DOM의 속성들은 모든 태그에 다 사용할 수 있다. 즉 document부터 head, body, script, div, span등 모든 태그에 다 지원된다.

document.getElementById('header').children

태그.firstChild, 태그.firstElementChild, 태그.lastChild, 태그.lastElementChild

모든 자식을 선택하는 대신 첫번째 자식만 선택하고 싶다면 firstChild 속성이 있다. 마지막을 선택하고 싶으면 lastChild가 있다.

document.body.firstChild; //<header>...</header>
document.body.lastChild; // <script>...</script>

firstElementChild, lastElementChild는 같은 역할이지만, 텍스트 노드는 무시한다.

태그.parentNode, 태그.parentElement

부모는 항상 한명이기때문에 단수형으로 표기

태그.previousSibling, 태그.nextSibling, 태그.previousElementSibling, 태그.nextElementSibling

document.getElementsByTagName('main')[0].nextSibling;

main 태그의 다음 형제 태그

태그.innerHTML, 태그.outerHTML

var footer = document.getElementsByTagName('footer')[0];
footer.innerHTML; // 'hello'
footer.innerHTML = 'goodbye';

hello -> goodbye

footer.outerHTML = '<footer><b>bold</b></footer>';

굵은 글씨의 bold 텍스트가 들어갑니다. outerHTML은 현재태그까지 포함한 문자열을 반환합니다

태그.clientHeight, 태그.clientWidth

태그의 margin, border, scrollbar을 제외한 높이와 너비를 반환합니다.

태그.offsetHeight, 태그.offsetWidth

태그의 margin만 제외한 높이와 너비를 반환합니다.

태그.scrollHeight, 태그.scrollWidth

스크롤 가능한 범위까지 포함한 태그의 높이와 너비를 반환합니다.

아래는 자주 쓰이는 태그의 메소드들입니다. DOM을 조작하려면 꼭 알아두어야 합니다.

태그.appendChild

이전 시간에 createElement() 함수로 만들었던 태그를 넣을 때 이 메소드가 필요합니다. 마지막 순서의 자식 태그로 추가됩니다.

var newElement = document.createElement('div');
document.body.appendChild(newElement);

위의 코드처럼 하면 body의 마지막 자식 태그로 div 태그가 하나 추가됩니다.

태그.removeChild

선택한 자식 태그를 삭제합니다.

document.body.removeChild(document.body.childNodes[document.body.childNodes.length - 1]);

body의 마지막 자식 태그를 삭제하는 코드입니다. document.body.childNodes[document.body.childNodes.length - 1]가 마지막 자식 태그를 선택하는 코드고요.

태그.insertBefore

appendChild가 자식 태그로 집어넣는 거라면 insertBefore 메소드는 자신의 형제 태그로 집어넣습니다. 자신 이전에요.

var newElement = document.createElement('div');
document.body.insertBefore(newElement, document.getElementById('header'));

위의 코드는 부모.insertBefore(넣을 태그, 기준 태그)입니다. 위의 코드는 body의 자식으로, header 이전에 새로 만든 div태그를 넣으라는 뜻이죠.

태그.cloneNode

자신을 복사합니다. 복사한 것을 저장해서 appendChild나 insertBefore로 집어넣으면 되겠죠?

var clone = document.getElementsByTagName('nav')[0].cloneNode();

문자열.match(패턴)

문자열에 해당하는 패턴이 있으면 배열로 해당하는 부분을 반환합니다. 해당하는 패턴이 없으면 null을 반환합니다.

문자열.search(패턴)

문자열에 해당하는 패턴이 있으면 그 위치(index)를 반환합니다. 해당하는 패턴이 없으면 -1을 반환합니다.

패턴.test(문자열)

패턴과 일치하면 true를 아니면 false를 반환하는 메소드입니다. 이를 통해서 패턴과 일치하는 지 확인할 수 있습니다.

패턴.exec(문자열)

패턴과 일치하면 배열을 반환하는데 첫 번째 요소는 일치하는 문자열을 반환하고, 두 번째 요소부터는 정규표현식의 group(괄호)을 반환합니다.

생성자

Date를 new Date() 라고 만들때 Date는 객체인데, new를 붙이고 함수처럼 호출하는 경우는 무엇일까?

이것은 생성자(constructor) 함수 이다. 객체를 생성하는 함수를 생성자 함수라고 부른다. 다른 언어에서는 class가 있지만, 자바스크립트에서는 없다. 생성자함수가 그 역할을 대신한다. 예를들면 사람 생성자를 만들면 다음과 같다.

function Person(name, gender) {
 this.name = name;
 this.gender = gender;
 this.sayHello = function() {
   alert(this.name + ' said "hello"');
}
 this... // 사람의속성과 메소드를 더 정의할 수 있다.
}

함수를 만들때 처럼 function을 쓰긴 했지만 함수와는 달리 대문자로 시작하게 만든다. 이것이 규칙이다. 새엇ㅇ자를 바탕으로 실제 사람 객체를 만들 수 있다. new 라는 키워드를 사용해서 호출한다. new 생성자(인자); 이런 방식이다.

var zero = new Person('Zero', 'm'); // Person { name : 'Zero', gender : 'm'}
var hero = new Person('Hero', 'f'); // Person { name : 'Hero', gender : 'f'}
zero.sayHello();
hero.sayHello();

Person 옆에 (name, gender)는 처음 만들때 매개변수를 받는 부분이을 알 수 있다. 그렇게 받은 매개변수들을 this.name, this.gender 에 저장한다. this는 바로 생성자 함수 자신을 가르킨다. 이렇게 this 에 저장된 것들은 new 를 통해 객체를 만들 때 그 객체에 적용된다.

프로토 타입

function Person(name, gender) {
 this.name = name;
 this.gender = gender;
}
Person.prototype.sayHello = function() {
 alert(this.name + ' said "Hello"');
}

this.sayHello 대신에 Person.prototype에 sayHello를 넣었다. prototype 객체는 사전 그대로 원형을 뜻한다. 원래의 모습을 말하는 것이다. 같은 생성자로부터 만들어진 객체들은 모두 이 원형 객체를 공유한다. 따라서 Person의 prototype 객체에 sayHello 라는 메소드를 넣으면 Person 생성자로 만든 모든 객체는 이 메소드 사용이 가능하다. 공유하고 있기 때문이다.

그런데 this.sayHello 보다 Person.prototype.sayHello로 넣는것이 더 효율적이다. prototype은 모든 객체가 공유하고 있어서 한 번만 만들어지지만, this에 넣은 것은 객체 하나를 만들 때마다 메소드도 하나씩 만들어지기 때문에 불필요한 메모리 낭비가 발생한다. 때문에 메소드 뿐 아니라 속성값까지도 prototype에 넣기도 한다.

prototype & _proto__

new Person('Nero', 'm');

위와같은 사람 객체를 만들면 _proto__라는 객체가 있다. 확인하면

{
 constructor : function Person(name, gender),
 sayHello : function() {},
 _proto__ : Object
}

constructor와 우리가 추가한 sayHello 그리고 _proto__가 있다.

proto가 바로 실제 객체를 만들 때 생성자의 prototype이 참조된 모습이다. 생성자의 prototype을 참조하기 때문에 proto와 prototype은 같다.

  • constructor는 생성자 함수 그 자체를 가리킴

  • prototype은 생성자 함수에 정의한 모든 객체가 공유할 원형

  • proto는 생성자 함수를 new로 호출할 때, 정의해두었던 prototype을 참조한 객체

  • prototype은 생성자 함수에 사용자가 직접 넣는 거고, proto는 new를 호출할 때 prototype을 참조하여 자동으로 만들어짐

  • 생성자에는 prototype, 생성자로부터 만들어진 객체에는 proto

  • 따라서 사용자는 prototype만 신경쓰면 된다. proto는 prototype이 제대로 구현되었는지 확인용으로 사용한다.

prototype, proto와 constructor의 관계

prototype과 constructor는 부모자식 관계라고 생각하면 됩니다. Person.prototype.constructor === Person; 입니다. 또한 Person.prototype === (Person생성자로 만들어진 객체).__proto__; 이기 때문에 (Person생성자로 만들어진 객체).__proto__.constructor === Person; 도 성립합니다.



출처 : https://www.zerocho.com/category/JavaScript/post/5740531574288ebc5f2ba97e

'Front-end' 카테고리의 다른 글

[VueJS] component  (0) 2019.05.13
[VueJS] method & event handling  (0) 2019.05.13
[VueJS] attribute binding  (0) 2019.05.13
[VueJS] list  (0) 2019.05.13
[VueJS] data binding  (0) 2019.05.12
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함