자바스크립트는 웹브라우저에서 HTML, CSS를 동적으로 제어하기 위해 만들어진 언어
웹브라우저 뿐 아니라 node.js, 구글 크롭 웹브라우저 플러그인,구글 스크립트, PDF, 각종 데스크탑 위젯에서 사용되는 자바스크립트에서도 적용한다.
var vscope = 'global';
function fscope(){
alert(vscope);
}
fscope();함수 밖에서 변수를 선언 → 전역변수
전역변수: 어플리케이션 전역에서 접근 가능한 변수
var vscope = 'global';
function fscope(){
var vscope = 'local';
alert('함수안 '+vscope);
}
fscope();
alert('함수밖 '+vscope);
지역변수 local은 함수 안에서만 사용 가능
var를 사용하지 않은 지역변수는 전역변수가 된다
function a (){
var i = 0;
}
for(var i = 0; i < 5; i++){
a();
document.write(i);
}
-> 실행결과 : 01234 ⇒ 지역변수 사용
function a (){
i = 0;
}
for(i = 0; i < 5; i++){
a();
document.write(i);
}
-> 실행결과: 무한반복 ⇒ 전역변수
MYAPP = {}
MYAPP.calculator = {
'left' : null,
'right' : null
}
MYAPP.coordinate = {
'left' : null,
'right' : null
}
MYAPP.calculator.left = 10;
MYAPP.calculator.right = 20;
function sum(){
return MYAPP.calculator.left + MYAPP.calculator.right;
}
document.write(sum());
불가피하게 전역변수를 사용할 경우 하나의 객체를 전역변수로 만들고 객체의 속성으로 변수를 관리
자바스크립트의 지역변수는 함수에서만 유효하다.
JavaScript의 함수가 다른 언어의 함수와 다른 점은 함수가 값이 될 수 있다
a = {
b:function(){
}
};
-> 함수는 값이라서 다른 함수의 인자로 전달 가능
function cal(func, num){
return func(num)
}
function increase(num){
return num+1
}
function decrease(num){
return num-1
}
alert(cal(increase, 1));
alert(cal(decrease, 1));
-> 함수 cal의 인자로 전달
: 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것
내부 함수
function outter(){
var title = 'coding everybody';
function inner(){
alert(title);
}
inner();
}
outter();
outter 내부에는 함수 inner 정의
내부함수는 외부함수의 지역변수에 접근 가능
function outter(){
var title = 'coding everybody';
return function(){
alert(title);
}
}
inner = outter();
inner()
내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성
외부함수의 지역변수 title이 소멸되지 않음
객체의 메소드에서 사용 가능
동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유
외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성됨
private한 속성을 사용 가능
function sum(){
var i, _sum = 0;
for(i = 0; i < arguments.length; i++){
document.write(i+' : '+arguments[i]+'<br />');
_sum += arguments[i];
}
return _sum;
}
document.write('result : ' + sum(1,2,3,4));
함수 안에서 사용할 수 있도록 그 이름이나 특성이 약속되어 있는 일종의 배열
함수 sum은 인자로 전달된 값을 모두 더해서 리턴하는 함수
arguments는 배열이 아니고 arguments 객체의 인스턴스다.
function zero(){
console.log(
'zero.length', zero.length,
'arguments', arguments.length
);
}
function one(arg1){
console.log(
'one.length', one.length,
'arguments', arguments.length
);
}
function two(arg1, arg2){
console.log(
'two.length', two.length,
'arguments', arguments.length
);
}
zero(); // zero.length 0 arguments 0
one('val1', 'val2'); // one.length 1 arguments 2
two('val1'); // two.length 2 arguments 1
-> arguments.length는 함수로 전달된 실제 인자의 수를 의미하고, 함수.length는 함수에 정의된 인자의 수를 의미
function sum(arg1, arg2){
return arg1+arg2;
}
alert(sum.apply(null, [1,2]))
o1.sum = sum;
alert(o1.sum());
delete o1.sum();
-> JavaScript에서 함수는 독립적인 객체로서 존재하고, apply나 call 메소드를 통해서 다른 객체의 소유물인 것처럼 실행할 수 있다
var person = {}
person.name = 'egoing';
person.introduce = function(){
return 'My name is '+this.name;
}
document.write(person.introduce()); -> 객체를 만드는 과정var person = {
'name' : 'egoing',
'introduce' : function(){
return 'My name is '+this.name;
}
}
document.write(person.introduce()); -> 다른 사람의 이름을 담을 객체가 필요할 때 => 생성자 사용function Person(){}
var p = new Person();
p.name = 'egoing';
p.introduce = function(){
return 'My name is '+this.name;
}
document.write(p.introduce()); -> 함수를 호출할 때 new을 붙이면 새로운 객체를 만든 후 리턴function Person(name){
this.name = name;
this.introduce = function(){
return 'My name is '+this.name;
}
}
var p1 = new Person('egoing');
document.write(p1.introduce()+"<br />");
var p2 = new Person('leezche');
document.write(p2.introduce()); -> 코드의 재사용성function func(){
alert('Hello?');
}
func();
window.func(); -> func 둘다 실행, 객체를 명시하지 않을 경우 암시적으로 window의 프로퍼티이다.function func(){
if(window === this){
document.write("window === this");
}
}
func(); -> 결과 : window===thisthis는 전역객체인 window와 같다.
객체의 소속인 메소드의 this는 그 객체를 가르킨다.
var funcThis = null;
function Func(){
funcThis = this;
}
var o1 = Func();
if(funcThis === window){
document.write('window <br />');
}
var o2 = new Func();
if(funcThis === o2){
document.write('o2 <br />');
}
-> 함수를 호출했을 때와 new를 이용해 생성자를 호출했을 때
=> 결과: window , o2
생성자는 빈 객체를 만들고 이 객체 내에서 this는 만들어진 객체를 가르킴
var o = {}
var p = {}
function func(){
switch(this){
case o:
document.write('o<br />');
break;
case p:
document.write('p<br />');
break;
case window:
document.write('window<br />');
break;
}
}
func();
func.apply(o);
func.apply(p);
-> apply와 call을 이용해 this 값 제어
=> 결과: window, o, p
function Person(name){
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
function Programmer(name){
this.name = name;
}
Programmer.prototype = new Person();
var p1 = new Programmer('egoing');
document.write(p1.introduce()+"<br />");
-> programmer 생성자를 만들어 prototype과 person의 객체를 연결하면 메소드인 introduce를 사용할 수 있다
: 객체의 원형
-> .prototype에 저장된 속성들은 생성자를 통해서 객체가 만들어질 때 그 객체에 연결
Ultra ← Super ← Sub
function Ultra(){}
Ultra.prototype.ultraProp = true;
function Super(){}
Super.prototype = new Ultra();
function Sub(){}
Sub.prototype = new Super();
var o = new Sub();
console.log(o.ultraProp);
객체 o에서 ultraProp를 찾는다.
없다면 Sub.prototype.ultraProp를 찾는다.
없다면 Super.prototype.ultraProp를 찾는다.
없다면 Ultra.prototype.ultraProp를 찾는다.
⇒ prototype chain
! Super.prototype=Ultra.prototype은 불가능
→ super 값을 변경하면 ultra도 변경함 ⇒ new 사용
: 자바스크립트가 기본적으로 가지고 있는 객체
Object, Function, Array, String, Boolean, Number, Math, Date, RegExp ⇒ 내장 객체
Array.prototype.rand = function(){
var index = Math.floor(this.length*Math.random());
return this[index];
}
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
console.log(arr.rand());
-> 배열에서 특정한 값을 랜덤하게 추출하는 코드
Math.floor : 숫자를 내림하여 가장 가까운 정수를 반환
: 객체의 가장 기본적인 형태를 가지고 있는 객체
-> 아무것도 상속받지 않는 순수한 객체
var grades = {'egoing': 10, 'k8805': 6, 'sorialgi': 80};
object를 확장하면 모든 객체가 접근할 수 있는 API 만들 수 있음
Object.prototype.contain = function(neddle) {
for(var name in this){
if(this[name] === neddle){
return true;
}
}
return false;
}
var o = {'name':'egoing', 'city':'seoul'}
console.log(o.contain('egoing'));
var a = ['egoing','leezche','grapittie'];
console.log(a.contain('leezche'));
egoing과 leezche가 포함되어 있는지 확인
결과: true, true
for(var name in o){
if(o.hasOwnProperty(name))
console.log(name);
}
-> hasOwnProperty는 인자로 전달된 속성의 이름이 객체의 속성인지 여부를 판단
=> 만약 prototype으로 상속 받은 객체라면 false
ar a = {'id':1};
var b = a;
b.id = 2;
console.log(a.id); // 2
-> 결과 : 2
=> 변수 b와 변수 a에 담긴 객체가 서로 같다
-> a=1과 a={’id’:1}
=> 전자는 데이터형이 숫자이고, 후자는 객체
=> 기본 데이터형은 복제되지만 참조 데이터형은 참조됨
var a = {'id':1};
function func(b){
b.id = 2;
}
func(a);
console.log(a.id); // 2
-> b는 객체 a의 레퍼런스
=> 이 값의 속성을 바꾸면 그 속성이 소속된 객체를 대상으로 수정 작업을 한것이어서 a에도 영향을 미침