자바스크립트 정리
웹에서 자바스크립트 코드를 테스트 해볼 수 있는 사이트 : http://jsbin.com/
C++이나 JAVA를 사용하던 입장에서 쉬울줄 알았는데, 존X 이해안되는 부분이 많다. {}이 scope를 생성하지 않는다는 사실도 충격적이고, 객체지향적 상속을 하기위한 prototype은 혼돈 그자체. functional langauge의 특성인건지… 완전 다른세상이여.
1. statements
// javascript sample code var name = "batmask"; var a = 2 + 1; var b += a; function sampleFunction(arg1, arg2){ // function code here }
자바스크립트는 자바와는 전혀 다른 언어지만, 기본 구문은 유사한 점이 많다.
2. data types
// variable var myVar; var myVar = undefined; // number var number1 = 100; var number2 = 100.1; // string var strVar1 = "string variable"; var strVar2 = 'single quatation string variable'; // boolean var isRight = true; isRight = false;
대부분의 스크립트 언어와 마찬가지로 변수나 함수 인자의 경우, 타입을 명시해줄 필요가 없다. 값을 대입하게 되면 해당 타입의 값이 된다. 변수의 정의는 가변형을 의미하는 ‘var’ 키워드를 사용한다. 변수도 그냥 객체로 생각하면 편하다.
데이터 타입으로는 number, string, boolean 을 갖고 있다.
3. operator
// arithmetic, assignment +, -, *, /, %, ++, --, =, +=, -=, *=, /=, %= //comparation ==, ===, !=, !==, >, <, >=, <= // logical operator &&, ||, ! // conditional operator variable = (condition) ? value1: value2 // bitwise operator &, |, ~, ^, <<, >>
다른 언어들과 거의 같은 연산자들을 사용한다. 눈여겨볼 점은 ‘==’ 와 ‘===’ 정도. ‘==’ 는 비교대상이 다른 타입인 경우, type conversion을 해서 그 값을 비교하므로 생각하던 값과 다른 값을 얻을 수 있다. 반면, ‘===’는 값과 타입이 모두 동일해야 true를 반환한다. ‘==’연산자는 evil twins라고까지 부르며 사용하지 않고 무조건 ‘===’연산자를 사용하도록 권고하고 있다.
다음은 스택 오버플로우 답변중 하나에서 가져온 evil twins(==)의 예이다.
'' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' \t\r\n ' == 0 // true
3. control statements
// if var myVar = 11; if (myVar < 10){ // code here }else if(myVar > 20){ // code here }else{ // code here } // switch var myVar = "Earth"; switch(myVar.toUpperCase()){ case "SUN": break; case "EARTH": break; case "MARS": break; default: } // for for(var i=0; i < 10; i++){ } // for in loop // only for iterating properties of object var me = { name: "batmask", age: 18, sex: "male" }; for(var prop in me){ } // while var isRight = false; while(!isRight){ isRight = true; } // do-while var isRight = false; do{ isRight = true; }while(!isRight);
switch-case문에서 C, C++처럼 정수만 가능하거나 하지 않다는 점. for-in 문을 사용할 때 java와 혼동해서 배열등에 사용하면 안된다는 점 정도. for-in문은 오직 객체의 properties를 나열할 때만 사용하도록 한다.
4. functions
// usage 1 function myFunc(arg1, arg2){ return arg1 + arg2; } myFunc(10, 20); // usage 2 var myFunc = function(arg1, arg2){ return arg1 + arg2; } myFunc(10, 20);
다른 언어들을 사용하다 자바스크립트를 처음 접하는 나로서는 첫번째 사용법이 훨씬 직관적이다. 데이터 타입을 명시할 필요가 없으므로, 함수 인자들도 테이터 타입에 대한 것은 전혀 필요없다.
5. objects
// create object without class declaration var me = { name: "batmask", age: 18, say: function(statement){ return "I say " + statement; } }; // usage console.log(me.name); console.log(me['age']); document.getElementById("result").innerHTML = me.say("What the fxxx!"); console.log(me.marrage = false);
자바스크립트는 모든 변수를 객체로 생각하면 될 정도로 객체는 중요하다. 위의 예는 단일 객체를 생성하는 예로 C++, java등을 접하다 보면 매우 낯설게 느껴진다. property 와 그 값이 ‘:’ 로 구분되어 있다. 왼쪽이 변수라고 생각하면 될듯하다. 각 property는 ‘,’ 로 구분하고 있다. ‘;’ 과 혼동하기 쉽다. 뒤에 생성자를 이용하는 경우에는 익숙한 ‘;’ 으로 구분하고 있다.
흥미로운 부분은 속성을 참조하는 경우 다른 객체지향 언어와 같이 dot notation을 사용하기도 하지만, 마치 배열처럼 ‘[ ]’ 에 속성 이름을 넣어 참조도 가능하다. 배열보다는 맵이라고 하는게 어울리겠다. ‘marrage’ 속성은 객체 생성시 없던 값이지만, 마치 있던 것처럼 값을 할당하고 있다. 이처럼 객체 생성시 만들지 않았던 property라도 언제든지 뒤에 추가할 수 있다.
// create object from Object constructor var me = new Object(); me.name = "batmask"; me.age = 18; me.say = function(statement){ this.statement = statement; return "I say " + statement; };
객체를 생성하는 두번째 방법이다. 모든 객체의 상위 객체인 Object의 생성자를 이용하는 방법이다. 이경우, 속성과 값을 일일이 나열해서 부여할 수 밖에 없다. say() 함수를 보면, 함수내에서 좀 억지로 ‘statement’ property에 값을 할당하는 구문이 보인다. 이처럼 메소드내에서 객체 속성에 접근하기 위해선 반드시 ‘this’키워드를 사용해야 한다. 이거 말하려고 어거지로 한줄 넣었다.
function Person(name, age){ this.name = name; this.age = age; this.statement = "Hi"; this.say = function(statement){ this.statement = statement; return "I say " + statement; }; } var me = new Person("batmask", 18); me.say("What the ...");
마지막으로 생성자를 이용한 객체 생성으로, 기존에 C++, java를 했던 나에게 가장 익숙한 형태의 객체 생성 방법이다. 다음으로 객체지향적 특성인 상속과 관련된 prototype을 알아보자.
function Person(name, age){ this.name = name; this.age = age; } function Korean(name, age){ this.prototype = new Person(name, age); this.name = name; this.age = age; this.say = function(statement){ return "내가 말하길, " + statement; }; } var me = new Korean("batmask", 18); var you = new Korean("marry", 20); Korean.prototype.marrage = false; // usage console.log(me.name); console.log(you.name); document.getElementById("result").innerHTML = me.say("What the ..."); console.log(me.marrage);
자바스크립트에는 클래스가 없다. 그렇기 때문에 상속은 객체의 복사를 통해 이루어진다. 프로토타입도 하나의 객체이기 때문에 여기에 속성을 추가 가능하다. 위 예에서 마지막줄에 ‘marrage’ 속성을 추가하고 있다. 주의사항은 자바스크립트에서 제공하고 있는 객체들의 프로토타입은 변경하지 말아야한다.
prototype.apply() 와 prototype.call()
좀 어려운 개념이지만 객체지향 구현을 위해 꼭 알아야 하는 내용이니, 좀 더 찾아보더라도 확실하게 알아야겠다.
*참고 : https://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
*참고 : javascript inheritance
* 참고 : 아… 뭐 여기저기 설명이 다 제각각이냐 ㅜㅜ http://javascript.info/tutorial/inheritance
* 참고 : 한글인데, 조금 읽어봤지만 좋아보인다. http://unikys.tistory.com/320 <- 친절하고 많이알고 설명 매우 좋다. 자바스크립트 관련 다른 글들도 있으니 추천.
6. scope
자바스크립트의 scope는 다른 언어와 다르게 동작하기 때문에 주의를 요한다.
* 참고 : http://www.w3schools.com/js/js_scope.asp
– local scope : 함수 안에 선언된 변수는 함수안에서만 유효한 local scope를 갖는다.
function func(){ var localVar = "This is local variable."; }
다른 언어가 블럭단위 scope를 갖는데에 반해, 자바스크립트는 함수단위 scope를 갖는다. 즉, 블럭안에 선언한 변수도 같은 함수내에선 참조가능하다.
function func(){ ... while(true){ var c = "Can you see me?"; break; } c = "Yes, I can"; }
– gloval scope : 함수 외부에서 선언된 변수는 global scope를 갖는다.
var glovalVar = "This is gloval variable."; function func(){ }
혼란스러울수 있지만, 함수 내에서 선언없이 사용하는 변수는 자동으로 global scope를 갖는다.
function func(){ glovalVar = "This is gloval variable."; } glovalVar = "ok.";
7.data structure
8.etc.