객체의 이해


자바스크립트 객체는 프로퍼티가 키/값 쌍으로 되어 있는 만큼 해시 맵에 빗대어 생각하면 이해하기 쉽다. 객체 프로퍼티에 접근할 때는 점 표기법 또는 각괄호 표기법 중 무엇을 해도 상관없다. 프로퍼티에 값을 할당하면 언제든 객체에 새 프로퍼티를 추가 할 수 있으며 delete 연산자를 사용하면 언제든 프로퍼티를 제거할 수 있다. 프로퍼티의 존재 여부는 프로퍼티 이름과 객체를 in 연산자와 함께 사용하면 알 수 있다. 이때 고유 프로퍼티만 확인하고 싶다면 모든 객체에 대 포함되어 있는 hasOwnProperty()를 사용하면 된다. 모든 객체 프로퍼티는 기본적으로 열거 가능하다. 열거 가능하다는 말은 for-in 반복문이나 Object.keys()를 사용할 때 볼 수 있다는 뜻이다.


프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 나누어진다. 데이터 프로퍼티는 값을 담아두기 위한 공간이므로 이 프로퍼티에서 값을 읽거나 저장할 수 있다. 데이터 프로퍼티에 함수를 담아두면 이 프로퍼티는 객체의 메소드로 취급된다. 데이터 프로퍼티와 달리 접근자 프로퍼티 자체에는 데이터를 저장할 수 없다. 접근자 프로퍼티는 게터와 세터를 조합하여 특정 동작을 수행한다. 데이터 프로퍼티와 접근자 프로퍼티 모두 객체 리터럴 표기법을 사용해 만들 수 있다.

 

모든 프로퍼티에는 관련된 내부 속성이 몇 가지 있으며 이러한 속성이 프로퍼티가 어떻게 동작하는지 결정한다. 데이터 프로퍼티와 접근자 프로퍼티에는 둘다 Enumerable Configurable 이라는 속성이 있다. 데이터 프로퍼티에는 WritableValue라는 속성이 추가로 있는 반면, 접근자 프로퍼티에는 GetSet 속성이 더 있다. 모든 프로퍼티의 EnumerableConfigurable 속성은 true가 기본 값이며 데이터 프로퍼티의 Writable 속성 역시 true가 기본 값이다. Object.defineProperty() 또는 Object.defindeProperties()를 사용하면 속성을 변경할 수 있으며 Object.getOwnPropertyDescriptor()를 사용하면 설정된 속성 값을 가져올 수 있다.

 

객체의 프로퍼티를 수정할 수 없게 만드는 방법은 세 가지가 있다. Object.preventExtensions()를 사용하면 객체에 프로퍼티를 추가할 수 없다. object.seal() 메소드를 사용하면 봉인된 객체를 만들 수 있는데 봉인된 객체는 확장 불가능해지며 객체의 프로퍼티는 설정 불가능해진다. Object.freeze()를 사용해 객체를 동결하면 객체가 봉인되는 것은 물론 데이터 프로퍼티에 값을 저장할 수도 없게 된다. 확장 불가능한 객체를 다룰 때는 잘못된 방식으로 객체에 접근했을 때 에러가 발생할 수 있도록 엄격한 모드를 사용하는 것이 좋다.

 

 

 자바스크립트의 객체는 동적이기 때문에 언제라도 바꿀 수 있다. 클래스 기반 언어는 클래스 정의에 따라 객체를 수정할 수 없도록 만들지만 자바스크립트 객체에는 이런 제약이 없다.

 

프로퍼티 정의

 

객체를 만드는 방법

1. Object 생성자를 사용하는 방법

2. 객체 리터럴 사용하는 방법

 

 

var parson 1 = { name :"kim"}

 

var person2 = new Object();

person2.name = "kim";

 

person1.age = 23

person2.age = 23

 

person1.name = "hong";

person2.name = "sim";

 

작성한 객체는 일부러 막아두지 않는 이상 언제든지 수정할 수 있다.

자바스크립트는 프로퍼티를 처음 객체에 추가할 때 객체에 있는 put 이라는 내부 메소드를 호출 한다. put 메소드는 객체에 프로퍼티 저장 공간을 생성한다. 이 동작은 수행하면 초기값은 물론 프로퍼티의 속성도 설정한다. 따라서 위의 예제에서 nameage 프로퍼티가 처음 정의 될 때마다 put 메소드가 호출된다.

 

put을 호출하면 객체에 고유프로퍼티가 만들어진다. 고유프로퍼티는 객체의 특정 인스턴스에 속해 있으며 인스턴스에 바로 저장된다.

 

기존 프로퍼티에 값을 할당 할때는 set이 호출 된다. set은 프로퍼티의 현재 값을 새 값으로 교체 한다.

 

프로퍼티 확인하기

 

잘못된 방법

 

if(person1.age){

 

}


 ****

이 방식의 문제점은 자바스크립트 타입 강제변환이 결과에 영향을 끼친다는 것이다. if 조건문은 주어진 값이 참스러운 값 (객체, 비어있지 않은 문자열, 0이 아닌 숫자, true) 이면 true로 취급하고 거짓스러운 값(null,undefined, false, NaN, 빈문자열) 이면 false로 취급한다. 객체 프로 퍼티에 거짓스러운 값이 저장될 수 있기 때문에 예제 코드와 같은 방식은 잘못 실행될 수 있다.

 

in 연산자 사용

in연산자는 특정 객체에 주어진 이름의 프로퍼티가 존재하는지 확인하고 존재하면 true를 반환한다. 사실 in연산자는 해시테이블에 주어진 키가 있는지 확인한다.

 

)

console.log("name" in person1) //true

consloe.log("age" in person1) //true

consloe.log("hobby" in person1) //false

 

 

자바스크립트에서 메소드는 함수를 참조하고 있는 프로퍼티이므로 메소드의 존재여부도 같은 방식으로 확인할 수 있다.

 

var person1 = {

name: "kim",

sayName: function(){

console.log(this.name)

}

 

}

 

console.log("sayName" in person1); // true

 


때로는 프로퍼티의 존재 여부를 확인하는 것에 그치지 않고 해당프로퍼티가 객체의 고유 프로퍼티인지도 확인해야 한다. in 연산자는 고유프로퍼티와 프로토타입 프로퍼티 둘다 찾기 때문에 고유 프로퍼티인지 확인하고 싶다면 다른 방법을 동원해야 한다. 모든 객체에 포함되어 있는 hasOwnProperty() 메소드는 주어진 프로퍼티가 객체에 존재하는 동시에 고유 프로퍼티일 때만 true를 반환한다.

 

var person1 = {

name: "kim",

sayName: function(){

console.log(this.name)

}

 

}

 

console.log("name" in person1); // true

console.log("person1.hasOwnProperty("name")); // true

 

console.log("toString" in person1); // true

console.log("person1.hasOwnProperty("toString")); // false

 

nameperson1의 고유 프로퍼티이므로 in 연산자와 hasOwnProperty()는 둘다 true를 반환한다. 하지만 toString() 메소드는 모든 객체에 포함되어 있는 프로토타입 프로퍼티이므로 in 연산자는 true를 반환하지만 hasOwnProperty()false를 반환한다.

 

프로퍼티 제거

프로퍼티 값을 null로 바꾸는 것만으로 프로퍼티가 객체에서 환전히 제거 되지 않는다. 값을 null로 바꾸는 동작은 set 내부 메소드를 null과 함께 실행하므로 앞에서 보았듯 프로퍼티의 값만 달라지게 된다.

객체에서 프로퍼티를 완전히 제거할 때는 delete 연산자를 사용해야 한다.

 

객체프로퍼티에서 delete 연산자를 사용하면 내부적으로 delete가 호출된다. 무사히 실행을 마쳤을 때 true를 반환한다.

 

 

var person1 = {

name: "kim",

sayName: function(){

console.log(this.name)

}

 

}

 

console.log("name" in person1) //true

 

delete person1.name;

console.log("name" in person1); //false

console.log(person1.name) //undefined

 

존재하지 않는 프로퍼티에 접근하면 undefinde가 반환된다

 

 

열거

객체에 추가하는 프로퍼티는 기본적으로 열거가 가능하다.

for- in 문을 사용해서 훑을 수 있다. 열거 가능 프로퍼티에는 Enumerable 이라는 내부속성이 true로 설정되어 있다.

 

var property;

for(property in object){

console.log("이름" + property);

console.log("" + object[property]);

}

 

 

객체 프로퍼티의 목록을 가져와야 한다면 ECMAScript 5에서 도입된 Object.keys()메소드가 유용하다.

 

var properties = Object.keys(object);

var I, len;

 

for(i=0, len=properties.length; i<len; i++){

console.log("name" + properties[i]);

console.log("value" + object[properties[i]]);

 

}

 

일반적으로 프로퍼티 이름 목록을 배열 형태로 다루고 싶을때는 Object.keys()를 사용하고 굳이 배열이 필요 없을 때는 for-in을 사용한다. for-in 반복문에서는 열거 가능한 프로토타입 프로퍼티도 반환하지만, object.keys()는 고유 프로퍼티만 반환한다.

 

모든 프로퍼티를 열거할 수 있는 것은 아니다. 객체의 네이티브 메소드는 대부분 Enumerable 속성이 false로 되어 있다. 특정 프로퍼티가 열거 가능한지 확인할 때는 propertyIsEnumerable() 메소드를 사용하면 된다. 이 메소드는 모든 객체에 포함되어 있다.

 

var person1 = {

name: "kim"

 

}

 

console.log("name" in person1) //true

console.log(person1.propertyIsEnumerable("name")); //true

 

var properties = Object.keys(person1);

 

console.log("length" in properties); // true

console.log(properties.propertyIsEnumerable("length")) //false

 

nameperson1에 직접 추가한 프로퍼티이므로 열거 가능하다. 반면 properties 배열의 length 프로퍼티는 Array.prototype의 내장 프로퍼티이므로 열거 가능하지 않다. 네이티브 프로퍼티는 대부분 기본적으로 열거 가능하지 않다.

 

프로퍼티 종류

1.데이터 프로퍼티 : 값을 포함하고 있다. put 메소드의 기본 동작을 통해 생성 된다.

2.접근자 프로퍼티: 값을 포함하지 않는 대신 프로퍼티를 읽었을 때 호출할 함수 게터(getter)와 값을 설정할 때 호추할 함수 세터(setter)를 정의 한다.


)

var person1 = {

name: "kim",

 

get name(){

console.log("name 읽는 중“);

return this.name;

},

 

set name(value){

 

console.log("name의 값을 %s로 설정하는 중", value);

this.name = value;

}

 

};

console.log(person1.name); //name 읽는 중 kim 출력

 

person1.name = "hong";

console.log(person1.name) //name의 값을 hong으로 설정하는 중 출력후 hong

 

이 예제는 name이라는 접근자 프로퍼티를 정의하고 있다. 접근자 프로퍼티에서 사용할 실제 값은 _name이라는 데이터 프로퍼티에 저장한다. name의 게터와 세터를 정의할 때는 function 키워드가 없다는 점만 제외하면 함수를 정의하는 문법과 비슷하다. get 또는 set이라는 특수한 키워드를 접근자 프로퍼티 이름앞에 사용하고 이름 뒤에는 괄호와 함수 코드를 입력한다. 게터는 값을 반환해야 하고 세터는 프로퍼티에 할당할 값을 인수로 전달 받을 수 있어야 한다.

 

프로퍼티 속성


공통속성

데이터 프로퍼티와 접근자 프로퍼티의 공통속성은 두가지다.

하나는 Enumerable 인데 프로퍼티가 열거 가능한지 정하는 속성이고 다른 하나는 Configurable로서 프로퍼티를 변경할 수 있는지 정하는 속성이다. Configurable 속성이 있는 설정가능 프로퍼티는 delete 연산자를 사용해 언제든 제거할 수 있고 속성도 언제든 변경할 수 있다. 다시 말해 설정 가능 프로퍼티는 데이터 프로퍼티를 접근자 프로퍼티로 바꾸거나 그 반대로 바꾸는 것도 가능하다. 객체의 모든 프로퍼티는 따로 설정을 하지 않는 한 열거 가능하며 설정 가능하다.

 

객체의 속성을 바꾸고 싶을 때는 object.defineProperty()메소드를 사용할 수 있다. Object.defineProperty() 메소드에는 인수를 세 개 전달하는 데 첫 번재 인수는 프로퍼티를 소유하고 있는 객체 이고 두 번째 인수는 프로퍼티 이름, 세 번째 인수는 설정할 프로퍼티 속성 값을 포함하고 있는 프로퍼티 서술자 객체이다.

 

var person1 = {name:"kim"}

//열거 불가능

Object.defineProperty(person1,"name",{

enumerable:false});

 

console.log("name" in person1); //true

console.log(person1.propertyIsEnumerable("name")); //false

 

var properties = Object.keys(person1);

console.log(properties.length) // 0

 

//설정불가능

Object.defineProperty(person1,"name",{

configurable:false

});

 

//

delete person1.name;

console.log("name" in person1); //true

console.log(person1.name); //kim

 

//에러

Object.defineProperty(person1,"name",{

configurable:true

});

 

 

데이터 프로퍼티 속성

1. value:

2. writable: 프로퍼티에 값을 저장할 수 있는지 정의하는 불리언 값

 

var person1 ={name : "kim"}


두개는 같다


var person1 = {};

Object.defineProperty(person1,"name",{

value: "kim",

enumerable:true,

configurable:true,

writable:true

 

});

 

Object.defineProperty()를 실행하면 먼저 해당 프로퍼티가 있는지 확인한다. 프로퍼티가 없다면 새 프로퍼티를 추가하고 프로퍼티 서술 객체에 정의한 대로 속성을 설정한다. 이 예제에서 nameperson1의 프로퍼티가 아니었기 때문에 새로 작성된다.

Object.defineProperty()를 사용해 새 프로퍼티를 정의할 때 서술자에 없는 속성은 모두 false로 설정된다. 따라서 필요한 속성은 반드시 서술자에 포함시켜 두어야 한다.


다음 예제는 Object.defineProperty()를 호출할 때 명시적으로 true라고 설정한 속성이 없었기 때문에 열거 불가능, 설정불가능, 쓰기 불가능한 name 프로퍼티를 만든다.

 

 

var person1 = {};

 

Object.defineProperty(person1,"name",{

value: "kim"

});

 

console.log("name" in person1); //true

console.log(person1.propertyIsEnumerable("name")); //false

 

delete person1.name;

console.log("name" in person1); //true

 

person1.name = "hong";

console.log(person1.name); //kim

 

접근자 프로퍼티 속성


접근자 프로퍼티는 저장할 값이 필요 없으므로 valuewritable 속성은 필요 없다

대신 setget 속성이 필요하다.

 

접근자 프로퍼티를 정의할 때 객체 리터럴 형식 대신 접근자 프로퍼티 속성을 사용하면 기존에 있던 객체에도 프로퍼티를 추가할 수 있다는 장점이 있다.

 

var person 1 ={_name:"kim",

 

get name(){

console.log("name 읽는 중")

return this._name;

},

set name(value){

console.log("name의 값을 %s로 설정하는중",value);

this._name=value;

}

 

}

 

이 코드는 다음과 같이 작성할 수 있다.

 

var person1= {_name:"kim"};

 

Object.defineProperty(person1,"name",{

get:function(){

console.log("name 읽는 중")

return this._name;

},

set:function(value){

console.log("name의 값을 %s로 설정하는중",value);

this._name=value;

 

},

enumerable:true,

configurable:true

});

 

Object.defineProperty()에 전달된 객체에 있는 get키와 set키는 값이 함수인 데이터 프로퍼티이다. 이 객체에서는 객체 리터럴 형태의 접근자를 사용할 수 없다.

접근자 프로퍼티에도 enumerable 이나 configurable 과 같은 속성을 설정하여 프로퍼티의 작동 방식을 조정할 수 있다. 설정안하면 false 가 설정된다.

 

여러프로퍼티 정의하기

Object.defineProperty() 대신 Object.defineProperties()를 사용하면 동시에 여러 프로퍼티를 설정할 수 있다. 이 메소드에는 인수를 두 개 전달한다. 첫 번째 인수는 대상 객체이고, 두 번째 인수는 정의할 프로퍼티의 정보를 담고 있는 객체이다.

 

var person1 = {};


Object.defineProperties(person1,{

 

//데이터를 정의할 데이터 프로퍼티

_name : {

value: "kim",

enumerable:true,

configurable:true,

writable:true

},

//접근자 프로퍼티

 

name :{

get:function(){

console.log("name 읽는 중");

return this._name;

},

set:function(value){

console.log("name의 값을 %s로 설정하는중",value);

this._name=value;

},

 

enumerable:true,

configurable:true

 

}

 

})

 

프로퍼티 속성 가져오기

Object.getOwnPropertyDescriptor() 메소드 사용

고유프로퍼티만 사용가능

첫 번째 인수: 대상객체

두 번째 인수: 정보를 가져올 프로퍼티의 이름

인수로 이름을 전달한 프로퍼티가 존재하면 프로퍼티의 속성 정보를 포함한 객체가 반환되며, 이 객체에는 configurable, enumerable을 비롯한 네 종류의 키가 설정되어 있다.

 

var person1 = {

name:"kim"

};

 

var descriptor = Object.getOwnPropertyDescriptor(person1,"name");

 

console.log(descriptor.enumerable); //true

console.log(descriptor.configurable); //true

console.log(descriptor.writable); //true

console.log(descriptor.vlaue); //kim

 

 도서: 객체지향 자바스크립트의 원리 정리

 

함수

자바스크립트에서 함수는 객체이다. 다른 객체에는 없는 함수만의 특성을 꼽으라면 call이라는 내부 속성을 들 수 있다. 내부속성은 코드로 접근할 수 없지만 코드의 동작을 정의한다.

 

선언과 표현식

함수에는 두가지 리터럴 형태가 있다.


1.함수 선언

 

function add(num,num2){

 

return num1 + num2

}

 


2.함수 표현식

 

var add = function add(num,num2){

 

return num1 + num2

}


 *참고

위의 두 함수는 비슷하지만 한가지 중요한 차이점이 있다.함수선언은 코드가 실행될 때 컨텍스트 상단에 끌여올려진다다시 말해 함수를 호출하는 코드가 함수를 선언한 코드보다 앞에 있어도 에러가 발생하지 않는다는 뜻이다.

 

var result = add(5,5);

 

function add(num,num2){

 

return num1 + num2

}

 

함수 표현식은 변수를 통해서만 함수를 참조하기 때문에 호이스팅 되지 않는다.


var result = add(5,5);

 

var add = function add(num,num2){

 

return num1 + num2

}

 

값으로서의 함수

, 함수를 변수에 할당할 수도 있고 객체에 추가할 수도 있으며 다른 함수에 인수로 전달하거나 함수에서 함수를 반환 할 수도 있다.

 

function say(){

console.log("hi");

}

 

say() ; // hi

 

var say2 = say;

 

say2(); // hi 출력

say라는 함수를 만드는 함수 선언이 있다. 그 후에 만들어진 say2 라는 변수에 say의 값을 할당했다. saysay2는 이제 같은 함수를 가리킨다.

 

함수를 다른 함수에 인수로 전달할 수 도 있다.

 

var score = [4, 11, 2, 10, 3, 1];

 

/* 오류 */

score.sort(); // 1, 10, 11, 2, 3, 4

// ASCII 문자 순서로 정렬되어 숫자의 크기대로 나오지 않음

 

/* 정상 동작 */

score.sort(function(a, b) { // 오름차순

return a - b;

// 1, 2, 3, 4, 10, 11

});

 

인수

자바스크립트 함수의 다른 특성 중 하나는 인수를 몇 개 전달하든 에러가 발생하지 않는다는 것이다. 이는 함수의 인수가 실제로는 배열과 비슷한 arguments라는 구조체에 저장되기 때문이다. 평범한 자바스크립트 배열과 마찬가지로 arguments에 담을 수 있는 값은 개수 제한이 없다. 저장된 인수는 숫자 인덱스로 접근할 수 있으며 length 속성을 사용하면 저장된 인수의 개수를 알 수 있다.

함수 안에서 arguments 객체가 자동으로 만들어 진다. 

참고: arguments 객체는 Array의 인스턴스가 아니기 때문에 배열 메소드를 사용할 수 없다. Array.isArray(arguments)는 항상 false를 반환 한다.

 

<script>

//매개변수와 관련된 두가지 수가 있다.

// 하나는 함수.length

// 하나는 arguments.length

 

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

</script>

 

 

오버로딩

대부분의 객체지향 언어는 한 함수에 여러 시그니쳐를 두는 함수 오버로딩을 지원한다. 함수 시그니처는 함수의 이름과 예상 인수 개수, 인수의 타입으로 이루어진다.

따라서 같은 함수라 해도 문자열 인수 한 개를 받는 시그니처와 숫자 인수 두 개를 받는 시그니처를 가질 수 있다.

하지만 자바스크립트 함수는 인수의 개수에 제한이 없으며 인수의 타입은 아예 정하지 않는다. 때문에 함수 오버로딩도 없다.

 

function say(msg){

console.log(msg);

}

 

function say(){

console.log("defalt msg");

}

 

say("hi") // defalt msg 출력

 

자바스크립트에서는 같은 이름을 가진 함수를 여러개 정의 하려고 할 때 마지막에 정의된 함수가 이긴다. 함수도 객체이기 때문에 두 번째에 있는 함수가 say에 재할당 되기 때문이다.

 

함수 오버로딩을 흉내낼 수 있는 방법

arguments 객체를 이용해서 함수에 전달된 인수의 개수를 구하고 이를 이용해 수행할 동작을 정의 하면 된다.

 

function say(msg){

if(arguments.length ===0 ){

msg = "defalt msg";

}

console.log(msg);

}

say("hi"); //hi 출력

 

say() 함수는 전달된 인수의 개수에 따라 다르게 동작한다. 전달된 인수가 없다면 (arguments.length ===0) 이 실행된다. 전달된 인수가 있을 때는 첫 번째 인수가 메시지로 사용된다. 타입까지 확인하고 싶다면 typeof 연산자와 intanceof 연산자를 이용한다.

  

객체 메소드

 

var person = {

name : "kim",

sayName: function(){

console.log(person.name);

}

 

}

 

person.sayName(); // kim 출력

 

this 객체

say() 메소드는 person.name을 직접 참조하고 있어서 객체와 메소드 간에 강한 결합이 만들어졌는데, 이는 문제의 소지가 많은 방법이다. 첫째, 변수 이름을 바꿀 때는 반드시 메소드 안에 있는 참조 코드도 바꿔줘야 한다. 둘째, 이런 식으로 강한 결합이 이루어지면 같은 함수를 여러 객체에 사용하기 어렵다.

 

문제 해결 방법은?

 자바스크립트의 모든 스코프에는 함수를 호출하는 객체를 뜻하는 this 객체가 있다. 전역 스코프에서 this는 전역 객체(웹브라우저에서는 window)를 참조한다. 객체에 붙어있는 함수를 호출하면 this의 값은 해당 객체가 된다. 따라서 메소드 안에서라면 객체를 직접 참조하는 대신 this를 참조할 수 있다.

 

var person = {

name : "kim",

sayName: function(){

console.log(this.name);

}

 

}

person.sayName(); // kim 출력

 

이제는 변수의 이름을 쉽게 바꿀 수 있으며 say() 함수를 다른 객체에 재사용하기도 쉬워졌다.

 

function sayAll(){

console.log(this.name);

}

 

// 두 객체 리터럴을 만들었고,

//sayNamesayAll 함수를 할당했다.

//함수는 참조값이므로 객체가 몇 개든 상관없이 객체의 속성으로

//함수를 할당할 수 있다.

 

var person1 = {

name : "kim",

sayName: sayAll

 

}

 

 

var person2 = {

name : "park",

sayName : sayAll

 

}

 

var name = "sim";

 

person1.sayName(); // kim

person2.sayName(); //park

 

sayAll(); //sim

 

 

this 값 변경

일반적으로 this 값은 자동으로 할당되지만 목적에 따라 바꿀수도 있다. 자바스크립트에서 this의 값을 바꿀 때 사용할 수 있는 함수 메소드는 세 종류가 있다. 함수도 객체이므로 메소드가 있다.

 

1.call 메소드

2.apply 메소드

3.bind 메소드

 

*call()

메소드는 this의 값을 바꾸는 것은 물론 인수도 전달하며 함수를 실행할 수 있다. call() 메소드의 첫 번째 인수는 함수를 실행할 때 this로서 사용될 값이다. 두 번째 인수부터는 함수를 실행할 때 그대로 전달된다. 다음 코드는 인수를 한 개 전달 받도록 한 것이다.

 

function say(label){

 

console.log(label+ ":"+ this.name);

}

 

var person1 = {

name: "kim"

}

 

 

 

var person2 = {

name: "park"

}

 

var name = "hong";

 

say.call(this,"global"); //global: hong 출력

say.call(person1,"person1"); //person1: kim 출력

say.call(person2,"person2"); //gperson2: park 출력

 

*apply() 메소드

apply() 메소드는 call()과 완전히 똑같이 동작하지만 인수를 두 개만 사용한다는 점이 다르다. apply() 메소드의 첫 번째 인수는 this로 사용할 값이고, 두 번째 인수는 함수에 전달할 인수를 담고 있는 배열 또는 배열과 유사한 객체이다. 즉 두 번째 인수로 arguments를 전달할 수도 있다.

 

function say(label){

 

console.log(label+ ":"+ this.name);

}

 

var person1 = {

name: "kim"

}

 

var person2 = {

name: "park"

}

 

var name = "hong";

 

say.applyl(this,["global"]); //global: hong 출력

say.apply(person1,["person1"]); //person1: kim 출력

say.apply(person2,["person2"]); //gperson2: park 출력

 

데이터가 이미 배열 형태로 존재한다면 apply()를 사용하는 편이 좋고 데이터가 개별 변수로 존재한다면 call()을 사용하는 편이 좋다.

 

요약

자바스크립트의 함수는 매우 특이하다. 함수도 객체이기 때문에 접근하고 복사하고 다시 정의할 수도 있고 다른 객체 값을 다루듯 사용할 수 있다. 자바스크립트에서 함수와 다른 객체의 가장 큰 차이점은 특수한 내부 속성 call 의 존재다. call에는 함수의 실행 동작이 정의되어 있다. typeof 연산자는 객체에 call 내부 프로퍼티가 있는지 찾아보고 있으면 function을 반환한다.

함수 리터럴 형식은 선언과 표현식이라는 두 종류가 있다. 함수 선언은 function 키워드 다음에 함수의 이름이 오며, 함수가 선언된 컨텍스트의 가장 위에서 정의된 것처럼 다루어진다. 함수 표현식은 평범한 값처럼 사용할 수 있어 할당 표현식, 함수 인수, 다른 함수의 반환 값등에 사용된다.

함수는 객체이기 때문에 function이라는 생성자가 존재한다. 자바스크립트에는 클래스라는 개념이 없기 때문에 함수 및 다른 객체만을 사용해 집합과 상속을 구현해야 한다.

 

 도서 객체지향 자바스크립트의 원리 정리

원시타입과 참조타입


자바스크립트에서는 원시 타입(primitive type) 참조 타입(reference type)이라는 두 가지 자료형을 제공한다.

숫자, 불린값, null과 undefined는 원시 타입이다. 객체, 배열, 함수는 참조 타입이다.

원시 타입 데이터는 변수에 할당될 때 메모리 상에 고정된 크기로 저장되고 해당 변수가 원시 데이터 값을 보관한다.

참조 타입 데이터는 크기가 정해져 있지 않고 변수에 할당될 때 값이 직접 해당 변수에 저장될 수 없으며, 변수에는 데이터에 대한 참조만 저장된다. 참조는 참조 타입 데이터의 주소이지 해당 데이터의 값이 아니다.

원시 타입 변수 복사

각 변수 간에 원시 타입 데이터를 복사할 경우 데이터의 값이 복사된다. 다음 예제를 보자.

var x = 100;        // 원시 타입 데이터를 선언
var y = x;          // 값을 새 변수에 복사
x = 99;             // 'x'의 값을 변경
console.log(y);     // 100, 'y'의 값은 변경되지 않음

참조 타입 변수 복사

각 변수 간에 참조 타입 데이터를 복사할 경우 데이터의 참조가 복사된다. 다음 예제를 보자.

var x = {count: 100};   // 참조 타입 데이터를 선언
var y = x;              // 참조를 새 변수에 복사
x.count=99;             // 참조 타입 데이터를 변경
console.log(y.count);   // 99, 'x'와 'y'는 동일한 참조를 담고 있으며, 따라서 동일한 객체를 가리킴


참조:http://codingnuri.com/javascript-tutorial/javascript-primitive-types-and-reference-types.html


자바스크립트에서 데이터 대부분은 객체이거나 객체를 통해 접근하는 값이다. 자바스크립트는 함수조차 객체로 표현하며 덕분에 자바스크립트의 함수는 일급함수이다.

원시타입과 참조타입: 두 타입모두 객체를 통해서 접근하지만 서로 다르게 동작하므로 차이점을 익혀두는게 좋다.

 

타입이란?

자바스크립트에 클래스라는 개념은 엇지만 이를 대체할 타입이라는 개념이 존재하며 타입은 크게 두 종류로 구분한다.

1.원시타입: 단순한 데이터를 저장하는 원시타입

2.참조타입: 객체로 저장되고 메모리 상의 주소를 가리킨다.

 

원시타입은 스택에 저장하고 참조는 힙에 저장하여 원시타입과 참조 타입을 구분하고 있지만 자바스크립트는 그렇지 않다. 자바스크립트에서는 변수 객체의 스코프를 따라 변수를 추적한다. 원시타입의 원시값은 변수 객체에 저장되지만 참조타입에서 변수 객체에 저장되는 참조 값은 메모리에 있는 실제 객체를 가리키는 포인터이다.

 

원시타입종류

Boolean

Number

String

Null

Undefied

 

모든 원시타입에는 값을 표현하는 리터럴 형식이 있다. 리터럴 이란 코드에 직접 입력된 이름이나 가격처럼 변수에 저장되지 않은 값을 의미한다.

 

var name = "kim";

var count = 23;

var found = true;

 

원시 값을 변수에 할당하면 값이 변수로 복사된다.

 

var a = "red";

var b = a;    //red

 

a,b는 같은 값을 가지고 있지만 두 값은 완전히 별개의 값이며 b에 아무런 영향을 주지 않고 a의 값을 바꿀 수 있다. 이는 두 값이 각 값당 하나씩 할당된 서로 다른 영역에 저장되어 있기 때문이다.

원시 값을 가지고 있는 각 변수는 독립된 저장 공간을 사용하기 때문에 다른 변수의 값을 바꿔도 영향을 받지 않는다.

 

var a = 'red';

var b = a;

console.log(a); //red

console.log(b); //red

 

a = 'blue';

console.log(a) // blue;

console.log(b) // red;

 

원시타입 종류 확인

type of 연산자로 확인

type of 연산자를 변수에 사용하면 변수에 저장된 데이터의 타입을 문자열로 반환한다.

 

참고 null 인지 아닌지 판단할 때

console.log(value === null);

 

등호 두 개를 사용하면 비교를 수행하기 전에 형변환을 하기 때문에 문자 ‘5’ 5는 같다. 등호 세 개를 이용하면 비교하지 않고 바로 비교를 한다.

 

원시메소드

원시타입인 문자열 숫자 불리언에는 사실 메소드가 존재한다.

var name = 'kang';

var lastname = name.toLowerCase();

 

원시 값에도 메소드가 존재하지만 원시 값 자체는 객체가 아니다. 자바스크립트의 원시 값은 다른 다른 언어와 유사한 경험을 주기 위해 마치 객체처럼 다룰 수 있게 되어있다.

 

참조타입

참조타입은 자바스크립트 객체를 나타내며 클래스가 없는 자바스크립트라는 언어에서 클래스와 가장 가까운 개념이다. 참조 값은 참조 타입의 인스턴스이며 객체와 같은 말이다. 객체는 순서가 없는 프로퍼티로 이루어져 있으며 프로퍼티는 이름과 값으로 구성되어 있다. 프로퍼티의 값이 함수 일 때 이 프로퍼티를 가르켜 메소드라고 부른다. 프로퍼티나 메소드를 다루려면 먼저 객체를 만들어야 한다.

 

객체 생성

객체를 만드는 것을 가리켜 인스턴스화 한다고 하는데, 자바스크립트에서 인스턴스화 방법은 두가지가 있다.


1. new 연산자와 생성자를 사용하는 것이다

생성자는 사실 new 연산자와 함께 사용하여 객체를 만들 수 있는 함수일 뿐이다. 관례상 자바스크립트에서 생성자의 이름은 첫 글자를 대문자로 시작하여 생성자가 아닌 다른 함수와 구분하고 있다.

참조 타입은 할당된 변수에 값을 직접 저장하지 않으므로 이 예제에서 object 변수에 저장된 값은 사실 객체 인스턴스가 아니라 객체가 있는 메모리상의 위치를 가리키는 포인터이다. 이것이 바로 원시 값과 객체의 가장큰 차이점인데, 원시값은 변수에 직접 값 자체가 저장된다. 객체를 변수에 할당하는 일은 사실 객체의 포인터를 할당하는 셈이다. 다시말해 어떤 변수를 다른 변수에 할당하면 두 변수는 모두 포인터의 복사본만 저장하고 있으므로 메모리상에서 똑같은 객체를 참조하게 된다.


) var object1 = new Object();

var object2 = object1;

 


객체 참조 제거

) var object1 = new Object();

object1 = null;

 

 

프로퍼티 추가 및 제거

자바스크립트의 특징 중 하나는 언제든 프로퍼티를 추가하고 삭제할 수 있다.

 

) var object1 = new Object();

var object2 = object1;

 

object1.hi = "hello";

console.log(object2.hi); //hello


object1object2는 같은 객체를 가리키고 있으므로 이 프로퍼티는 object2에서도 접근 할 수 있다.

 

내장타입 인스턴스화

 

Array 숫자 인텍스 값을 가진 순차 목록

Date 날짜와 시간

Error 실행 중 발생하는 에러

Function 함수

Object 일반적인 객체

RegExp 정규표현식

 

내장 참조 타입은 다음과 같이 new 연산자를 사용해 인스턴스로 만들 수 있다.

 

리터럴 형식

리터럴은 new 연산자와 객체의 생성자를 사용하여 명시적으로 객체를 만들지 않고도 참조 값을 만들 수 있는 문법이다.

 

객체 및 배열 리터럴

프로퍼티가 두 개 있는 객체 예)

var book = {name:"자바스크립트의 원리",

year: 2016

}

 

아래와 같다.


var book = new Object();

book.name = "객체지향";

book.year = 2014;


참고

객체 리터럴을 사용하면 실제로도 new Object()를 호출하지 않는다. 실제로 생성자를 호출하지 않지만 자바스크립트가 내부적으로 new Object()를 사용했을 때와 동일한 단계를 수행한다.

 

 

배열리터럴

var colors = ["red","blue","green"];

console.log(colors[0]); //red

 

이 코드는 다음과 같다.

 

var colors = new Array("red","blue","green")

console.log(colors[0])

 

함수리터럴

function reflect(value){

return value;

}

 

// 위코드는 다음과 같다.

var reflect = new Function ("value","return value");

 

이처럼 간단한 함수일때도 생성자를 사용하는 방법보다 리터럴을 사용하는 방법이 작성하기도 편하고 이해하기도 쉽다. 게다가 생성자 형태로 작성한 함수는 디버그하기 까다롭다. 자바스크립트 디버거는 생성자를 통해 작성된 함수를 인식하지 못하므로 이렇게 작성된 함수는 들여댜 볼 수 없다.

 

정규표현식 리터럴

var numbers = |\d+|g;

var numbers = new RegExp("||d", "g");


프로퍼티 접근

var array = [];

array.push(12345);

 

각괄호 표기법을 사용할 때는 다음과 같이 각괄호 안에 메소드 이름을 문자열로 입력한다.

 

var array = [];

array["push"](12345);

 

이 문법은 접근할 프로퍼티를 동적으로 정해야 할 때 유용하다.

 

var array = [];

var method = "push";

array[method](1234);

 

참조타입 확인 

instanceof 연산자 사용

 

var items = [];

var object = {};

 

function reflect(value){

return value;

}

 

console.log(items instanceof Array); //true

console.log(object instanceof Object);

 

-자바스크립트에서 모든 참조 타입은 object를 상속하므로 사실 모든 객체는 object의 인스턴스다.

 

배열확인

var items = [];

console.log(Array.isArray(items)); //true

 

참고:explore8이하에서는 지원 안됨


원시래퍼타입

 

var name = "kim";

var firstChar = name.charAt(0);

console.log(firstChar) //"k"

 

이때 내부에서 일어나는 일은 다음과 같다.

 

var name = "kim";

var temp = new String(name);

var firstChar = name.charAt(0);

temp = null;

console.log(firstChar) //"k"

 

두 번째 줄에서 원시 문자열을 객체처럼 취급했기 때문에 자바스크립트 엔진은 charAt(0)이 정상 적으로 작동하도록 String의 인스턴스를 만든다. 이렇게 작성한 String 객체는 한 문장만 실행하고 곧 다시 파괴되는데 이 과정을 가리켜 오토박싱이라고 한다. 일반적인 객체를 다루듯 문자열에 프로퍼티를 추가해보면 이를 확인 할 수 있다.

 

var name = "kim";

name.last = "tong";

console.log(name.last); //undefind

 

평범한 객체를 다룰 때는 언제든 프로퍼티를 추가할 수 있으며 추가된 프로퍼티는 일부러 제거하지 않는 한 추가된 상태 그대로 있다. 원시 값에 프로퍼티를 추가하려고 하면 원시 래퍼 타입이 임시로 만들어 지고 이 객체에 프로퍼티가 추가된다. 하지만 임시로 만들어진 원시 래퍼타입은 곧 파괴 되기 때문에 프로퍼티가 사라진 것처럼 보인다.

 

//실제로 자바스크립트 엔진이 하는 일

var name = "kim";

var temp = new String(name);

temp.last = "tong";

temp = null;

 

var temp = new String(name);

console.log(temp.last); //undefind

temp = null;

 

var name = "kim";

var count = 10;

var found = false;

 

console.log(name instanceof String); //false

console.log(count instanceof Number); //false

console.log(found instanceof Boolean); //false

 

임시 객체는 값을 읽을 때 만들어지기 때문에 instanceof 연산자는 false를 반환한다. instanceof 연산자가 실제로는 아무런 값도 읽지 않기 때문에 임시 객체도 만들어지지 않고 따라서 원시 값은 원시 래퍼 타입의 인스턴스가 아니라는 결과가 반환되는 것이다. 원시 래퍼 타입을 명시적으로 사용해 값을 생성하는 방법도 있지만 이때는 다른 문제가 발생한다.

 

var name = new String("kim");

var count = new Number(10);

var found = new Boolean(false);

 

console.log(typeof name);

console.log(typeof count);

console.log(typeof found);

//보다시피 원시 래퍼타입의 인스턴스를 만들면 객체가 만들어지기 때문에 typeof연산자를 사용한 결과는 의도한 것과 다르게 나타난다.

 

 

요약

자바스크립트에는 클래스가 없는 대신 타입이 존재한다. 각 변수나 데이터에는 그에 해당하는 특수한 원시 타입 또는 참조 타입이 존재한다. 다섯 가지 원시 타입은 주어진 컨텍스트 내에서 변수 객체에 바로 저장되는 단순한 값을 의미 한다.

typeof 연산자를 사용하면 원시타입의 종류를 확인할 수 있다.

하지만 nullnull은 비교해야 한다.

참조 타입은 클래스가 없는 자바스크립트에서 클래스와 가장 가까운 개념이며 객체는 참조 타입의 인스턴스다. new 연산자나 리터럴 형식을 사용하면 새로운 객체를 생성할 수 있다. 프로퍼티와 메소드에 접근할 때는 보통 점 표기 법을 사용하는데 각괄호 표기법을 대신 사용할 수도 있다. 자바스크립트에서는 함수도 객체이며, 어떤 값이 함수인지는 typeof 연산자를 사용해 확인할 수 있다. instanaceof 연산자는 주어진 객체가 어떤 참조 타입의 인스턴스인지 확인할 때 사용한다.

 

자바스크립트에는 String, Number, Boolean이라는 세 종류의 원시 래퍼 타입이 있어 원시 값을 마치 참조 값처럼 다룰 수 있도록 해주지만, 자동으로 생성한 임시 객체는 문장 하나를 완료하자마자 곧 파괴 된다. 원시 래퍼 타입의 인스턴스를 명시적으로 만들수도 있지만 이 방법은 혼란을 이야기할 소지가 있어 권장하지 않는다.

 

도서 객체지향 자바스크립트의 원리 정리

1.

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


//함수는 객체다

//함수 func는 function이라는 객체의 인스턴스다.

//따라서 func는 function이 가지고 있는 메소드들을 상속한다.

function func(){

}

func();




// 함수를 호출 하는 다른 방법

//함수 sum은 Function 객체의 인스턴스다. 그렇기 때문에 객체 Function의 메소드 apply를 호출 할수 있다. 

function sum(arg1, arg2){

    return arg1+arg2;

}

alert(sum.apply(null, [1,2]))


</script>

<BODY>


</BODY>

</HTML>




2.

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


o1 = {val1:1, val2:2, val3:3}

o2 = {v1:10, v2:50, v3:100, v4:25}


function sum(){


    var _sum = 0;

    for(name in this){

        _sum += this[name];

    }

    return _sum;

}



alert(sum.apply(o1)) // 6

alert(sum.apply(o2)) // 185



//sum.apply(o1)은 함수 sum을 객체 o1의 메소드로 만들고 sum을 호출한 후에 sum을 삭제한다. 

//sum의 o1 소속의 메소드가 된다는 것은 이렇게 바꿔 말할 수 있다.

// 함수 sum에서 this의 값이 전역객체가 아니라 o1이 된다는 의미다.

// 일반적인 객체지향 언어에서는 하나의 객체에 소속된 함수는 그 객체의 소유물이 된다. 

//하지만 JavaScript에서 함수는 독립적인 객체로서 존재하고, apply나 call 메소드를 통해서 다른 객체의 소유물인 것처럼 실행할 수 있다. 


</script>

<BODY>


</BODY>

</HTML>




1.

<!DOCTYPE html>

<html>

<head>

    <title>hamsoo</title>

</head>



<script>

//함수에는 arguments 라는 변수에 담긴 숨겨진 유사배열이 있다.

//arguments.length를 이용해서 함수로 전달된 인자의 개수를 알아낼 수도 있다.

//이러한 특성에 반복문을 결합하면 함수로 전달된 인자의 값을 순차적으로 가져올 수 있다.

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));


</script>



   </body>

</html>



2.

<!DOCTYPE html>

<html>

<head>

    <title>hamsoo</title>

</head>



<script>

//매개변수와 관련된 두가지 수가 있다.

// 하나는 함수.length

// 하나는 arguments.length


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

</script>




   </body>

</html>




1

<HTML>

<HEAD>

<TITLE> closure</TITLE>

</HEAD>

<script>


//내부함수가 외부함수에 접근 할 수 있다.

//내부함수는 외부함수의 지역변수에 접근할 수 있다.



function outter(){

var name = 'kang';

function inner(){

alert(name)

}

inner();


}


outter();

</script>

<BODY>


</BODY>

</HTML>



2
<HTML>
<HEAD>
<TITLE> closure</TITLE>
</HEAD>
<script>

//내부함수가 외부함수에 접근 할 수 있다.
//내부함수는 외부함수의 지역변수에 접근할 수 있다.


//외부함수
function outter(){
var name = 'kang';
return function inner(){
alert(name)
}


}

inner = outter();
inner();

//내부함수는 외부함수의 지역변수에 접근할 수 있다.
// 외부함수의 실행이 끝나서 외부함수가 소멸된 후에도 내부함수가 외부함수의 변수에 접근할 수 있다.
// 26행에서 함수 outter를 호출
// 그 결과가 inner에 담긴다.
//그리고 outter 함수는 종료된다. 지역변수도 소멸되어댜 한다.
// 하지만 inner() 함수를 실행 했을 때 kang이 출력된 것은 외부함수의 지역변수가 소멸되지 않았다는 것을 의미한다.
// 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성이 클로저다.

</script>
<BODY>

</BODY>
</HTML>


3.

<HTML>
<HEAD>
<TITLE> closure</TITLE>
</HEAD>
<script>

function movie(title){

return {
get_title : function(){ return title;},
set_title:  function(_title){title = _title}
}


}


a = movie('a_movie');
b = movie('b_movie');
alert(a.get_title());
alert(b.get_title());
a.set_title('change-movie-title');


alert(a.get_title());
alert(b.get_title());


//1.클로저는 객체의 메소드에서도 사용할 수 있다. 
//위의 예제는 함수의 리턴값으로 객체를 반환하고 있다.
//이 객체는 메소드 get_title,set_title을 가지고 있다.
//이 메소드들은 외부 함수인 factory-movie의 인자값으로 전달된 지역변수 title을 사용하고 있다.


//2.동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유한다.

//3.하지만 똑같은 외부함수 factory-movie의를 공유하고 있는 a와 b의 get_title의 결과는 서로 다르다.
//그것은 외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성되기 때문에 a와 b는 서로 완전히 독립된 객체가 된다.

//4.factory-movie의  지역변수  title은 2행에서 정의된 객체의 메소드에서만 접근할 수 있는 값이다.
//이말은 title의 값을 읽고 수정할수 있는 것은 factory-movie를 통해서 만들어진 객체 뿐이라는 의미다.
//js는 기본적으로 private 한 속성을 지원하지 않는데, 클로저의 이러한 특성을 이용해서 private한 속성을 사용할 수 있게 된다.

//5.참고 Private 속성은 객체의 외부에서는 접근 할 수 없는 외부에 감춰진 속성이나 메소드를 의미한다. 이를 통해서 객체의 내부에서만 사용해야 하는 값이 노출됨으로서 생길 수 있는 오류를 줄일 수 있다. 
//자바와 같은 언어에서는 이러한 특성을 언어 문법 차원에서 지원하고 있다.

</script>
<BODY>

</BODY>
</HTML>


4.
<HTML>
<HEAD>
<TITLE> hamsoo</TITLE>
</HEAD>
<script>

//var arr = []
//for(var i = 0; i < 5; i++){
//   arr[i] = function(){
//        return i;
//   }
// }
// for(var index in arr) {
//    console.log(arr[index]());
// }




var arr = []


for(var i = 0; i < 5; i++){

    arr[i] = function(id) {
return function(){ return id;}
}(i);
}


for(var index in arr) {
    console.log(arr[index]());
}

</script>
<BODY>

</BODY>
</HTML>


5.

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8"/>

</head>

<body>

<script>

var arr = []


console.log("START");


for(var i = 0; i < 5; i++){

console.log("A");

arr[i] = function(){

console.log("B");

console.log("i ===> "+i);

return i;

}

// console.log(arr);

// console.log("arr ===> "+arr[i]());


}


console.log("[for문 END]FINAL return값 i ===> "+i);


console.log("[for/in문 START]");


for(var index in arr) {

console.log("C");

console.log("index ====> "+index);

console.log("arr ===> "+arr[index]());

}

</script>

</body>

</html>


6.

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8"/>

</head>

<body>

<script>

var arr = []

console.log("START");

for(var i = 0; i < 5; i++){

arr[i] = (function(id){

console.log("A");

console.log("i ===> "+i);

return function(){

console.log("B");

console.log("id ===> "+id);

return id;

}

})(i);

// console.log("[for문]arr ===> "+arr[i]());

}

console.log("[for문 END]FINAL return값 i ===> "+i);

console.log("[for/in문 START]");

for(var index in arr) {

console.log("C");

console.log("index ====> "+index);

console.log("arr ===> "+arr[index]());

}

</script>

</body>

</html>

1.

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


// js에서는 함수도 객체다

//일종의 값이다.

//함수 a는 변수a에 담겨진 값이다.

function a(){}




// 함수는 객체의 값으로 포함될 수 있다. 

//객체의 속성값으로 담겨진 함수를 메소드라고 부른다.

car = {

    speed:function(){

    }

};




</script>

<BODY>


</BODY>

</HTML>



2

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>

//함수는 값이기 때문에 다른 함수의 인자로 전달 될 수도 있다.


// 계산기 함수

function cal(func,num){


return func(num);

}


//더하기 함수

function increase(num){


return num+1


}



//빼기 함수

function decrease(num){


return num-1

}



// 함수 cal 에 인자로 increase와 1을 전달한다.

//cal은 첫번째 인자를 받아 함수를 실행하고 그 함수의 매개변수로 1을 전달한다.

// 해당함수 increase가 실행되고 매개 변수 1을 받아 계산 후 cal 함수로 리턴한다.

//cal은 해당 값을 리턴한다.


alert(cal(increase,1));


alert(cal(decrease,1));






</script>

<BODY>


</BODY>

</HTML>


3

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


//함수는 함수의 리턴 값으로도 사용할 수 있다.


function cal(mode){


var funcs = {

'plus': function(left,right){return left+right},

'minus':function(left,right){return left-right}

}

//함수 리턴

return funcs[mode];


}



//cal에 인자 값으로 특정 값을 넣으면 함수 반환 

// 그함수에 인자 값 전달

// 계산후 리턴


alert(cal('plus')(2,1));

alert(cal('minus')(2,1));


</script>

<BODY>


</BODY>

</HTML>



4.

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


//배열 값으로도 사용가능하다.


//배열 선언

var process = [

function(input){return input + 10},

function(input){return input * input},

function(input){return input / 2}

];


var input = 1;


for(var i = 0;i<process.length;i++){


input = process[i](input);


}


alert(input);


<!-- 값으로서의 함수 : 자바스크립트에서 함수는 값으로도 쓰일 수 있다(변수에 담기, 객체 안에 저장하기, 다른 함수의 인자로 사용하기, 함수의 리턴값으로 사용하기, 배열의 값으로 사용하기 등)  -->

<!-- -> first-class-object,citizen이라함 -->


<!-- *객체 안에서 key는 변수 역할, 속성이라고도 부르고 value에 함수가 담긴다면 이는 메소드라 부른다 -->

<!-- - 콜백함수 : 함수가 다른 함수의 인자로 사용됨으로써 그 함수의 내용을 완전히 바꿀 수 있는 것. -->

<!-- - 비동기처리 : 시간이 오래 걸리는 작업을 나중에 처리해서 일련의 작업을 순서대로 처리하지 않음으로써 사용의 편의성을 높이는 기법. -->

<!-- (일반 환경에서는 보이지 않고 서버 환경에서 구동된다) - 대표적으로 Ajax라는 기법이있음 -->


</script>

<BODY>


</BODY>

</HTML>





함수.zip


<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>

var scope = 'car';

function funcScope(){

alert(scope);

}


funcScope();


//함수 밖에서 변수를 선언하면 그 변수는 전역변수가 된다.

//전역변수는 어떤 함수 안에서도 그 변수에 접근 할 수 있다.

</script>

<BODY>


</BODY>

</HTML>

2


<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>

//전역변수

var scope = 'out-car';

//함수

function funcScope(){

//지역변수

var scope = 'inner-bike';

alert("inner"+scope);

}


//호출

funcScope();

alert("out"+scope);

//결과는 inner bike -> outout-car

//지역변수의 유효범위는 함수 안

//같은 이름의 전역변수와 지역변수가 동시에 선언되었다면 지역변수가 우선됨.

</script>

<BODY>


</BODY>

</HTML>



3

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>

//전역변수

var scope = 'out-car';

//함수

function funcScope(){

//지역변수

scope = 'inner-bike';

alert("inner"+scope);

}


//호출

funcScope();

alert("out"+scope);

//결과는 inner bike -> out inner-bike

//var를 사용하지 않은 지역변수는 전역변수가 된다.

//전역변수는 사용하지 않는 것이 좋다. 

//변수를 선언할 때는 꼭 var를 붙이는 습관!

</script>

<BODY>


</BODY>

</HTML>



4.

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


//지역변수 사용

function a (){

    var i = 0;

}


for(var i = 0; i < 5; i++){

    a();

    document.write(i);

}


//같은 이름의 변수 i 지만 함수안에 지역변수로 선언되어서 for문에 영향을 안미친다.


</script>

<BODY>


</BODY>

</HTML>



5

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


//전역변수 사용 !

function a (){

     i = 0;

}


for(var i = 0; i < 5; i++){

    a();

    document.write(i);

}


//전역변수는 각기 다른 로직에서 사용하는 같은 이름의 변수값을 변경 시켜서 의도치 않은 

//문제를 발생시킨다.


</script>

<BODY>


</BODY>

</HTML>


6

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>

//전역변수를 사용해야 할 경우에는 하나의 객체를 전역변수로 만들고 객체의 속성으로 변수를 관리하는 방법을 사용한다.


//객체 선언

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;

}


//호출 //결과값 30

document.write(sum());


//전역변수를 객체로 만들어 속성으로 객체를 통해 변수를 관리하면 변수 이름이 같아도 값이 변경될 여지가 없다.!

</script>

<BODY>


</BODY>

</HTML>




7.


<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>

//전역변수를 사용하고 싶지 않다면 아래와 같이 익명함수를 호출함으로서 이러한 목적을 달성할 수 있다.


(function(){

//객체 선언

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;

}


//호출 //결과값 30

document.write(sum());

}())


// 자바스크립트에서 로직을 모듈화 하는 일반적인 방법

</script>

<BODY>


</BODY>

</HTML>



8

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>



for(var i=0; i <1;i++){


var name = 'wow';


}


alert(name);


//자바스크립트 변수는 함수에 대하 유효범위만을 제공한다. 

// for문 등에 선언된 변수를 for문 밖에서도 사용할 수 있다.

// but 다른 언어에서는 안됨


</script>

<BODY>


</BODY>

</HTML>



9.

<HTML>

<HEAD>

<TITLE> hamsoo</TITLE>

</HEAD>

<script>


//자바스크립트는 함수가 선언된 시점에서 유효범위를 가진다. 블록안에서 함수를 호출해도 그 블록의 지역변수를 가져오지 않는다

var i = 5;

 

function a(){

    var i = 10;

    b();

}

 

function b(){

    document.write(i);

}

 

a();


//정리


<!-- 자바스크립트 변수는 var 생성자의 유무에 따라 같은 이름의 변수라도 사용할 수 있는 범위가 달라진다 -->

<!-- 이것을 자바스크립트의 유효 범위가 다르다고 하는데 유효범위에 따른 변수의 종류에 대한 구분은 지역변수와 전역변수로 나눠진다 -->

<!-- 함수 밖에서 선언한 var로 변수는 전역변수가 되며, 함수블럭 내에서 var로 선언한 변수는 지역변수가 된다. -->

<!-- 지역변수는 같은이름의 지역변수가 존재해도 다른 객체로 취급되어 변수명의 재사용성이 훨씬 높아진다 -->

<!-- 지역젼수는 수명이 짧아 선언된 위상의 코드블럭이 종료되면 자동으로 사라진다 -->

<!-- 전역변수는 보안과 가독성을 높이기 위해 보통 사용하지 않는다 -->

<!-- 전역변수를 사용하고 싶을때 익명함수를 이용해 전역변수를 모아놓은 하나의 객체로 선언한다. 이것은 이전 강의의 모듈화에 이어지는 내용이다 -->

<!-- 자바스크립트는 함수가 선언된 시점에서 유효범위를 가진다. 블록안에서 함수를 호출해도 그 블록의 지역변수를 가져오지 않는다 -->

</script>

<BODY>


</BODY>

</HTML>





폼 요소 선택하기

셀렉터

설명

:button

button type 특성값이 button인 요소들을 리턴

:checkbox

type 특성이 checkboxinput 요소들을 리턴

:checked

체크박스 및 라디오 버튼들중 체크된 요소들 리턴

:disabled

비활성화된 모든 요소 리턴

:enabled

활성화된 모든 요소 리턴

:focus

현재 포커스를 가진 요소 리턴

:file

모든 파일 입력 요소들을 리턴한다.

:image

모든 이미지 요소들을 리턴한다.

:input

모든 button, input select textarea 요소들을 리턴한다.

:password

모든 비밀번호 입력 요소들을 가져온다.

:radio

모든 라디오 입력 요소들을 가져온다.

:reset

모든 리셋 버튼 요소들을 가져온다.

:selected

선택된 모든 요소들을 가져온다.

:submit

button type 특성 값이 submit인 요소들을 가져온다.

:text

type 특성 값이 text 이거나 특성값이 존재하지 않는 모든 input 요소들을 가져 온다.

 

폼요소와 이벤트

 

메서드

설명

.val()

input,select textarea 요소에 주로 사용된다. 객체 집합내 첫 번째 요소의 값을 가져오거나 모든 요소들의 값을 수정할 때 사용된다.

.filter()

두 번째 셀렉터를 이용하여 제이쿼리 객체집합을 필터링 한다.

:is()

폼 요소가 선택 혹은 체크되어 있는지 확인 할 때 주로 사용한다.

$.isNumeric()

값이 숫자 값으로 표현될 수 있는지를 불리언 값으로 리턴한다.

.on()

모든 이벤트를 처리할 때 사용한다.

blur

요소가 포커스를 잃을 때 발생한다.

change

입력 요소의 값이 변경 되었을 때 발생한다.

focus

요소가 포커스를 얻을 때 발생한다.

select

select 요소의 옵션 아이템이 변경되었을 때 발생한다.

submit

폼데이터를 전송할 때 발생한다.

 

 

 예)

 .html

  <body>

    <div id="page">

      <h1 id="header">List</h1>

      <h2>Buy groceries</h2>

      <ul>

        <li id="one" class="hot"><em>fresh</em> figs</li>

        <li id="two" class="hot">pine nuts</li>

        <li id="three" class="hot">honey</li>

        <li id="four">balsamic vinegar</li>

      </ul>

      <div id="newItemButton"><button href="#" id="showForm">new item</button></div>

      <form id="newItemForm">

        <input type="text" id="itemDescription" placeholder="Add description..." />

        <input type="submit" id="addButton" value="add" />

      </form>

    </div>

 

 

 .js

$(function() {


  var $newItemButton = $('#newItemButton');

  var $newItemForm = $('#newItemForm');

  var $textInput = $('input:text');


  $newItemButton.show();

  $newItemForm.hide();


  $('#showForm').on('click', function(){

    $newItemButton.hide();

    $newItemForm.show();

  });


  $newItemForm.on('submit', function(e){

    e.preventDefault();

    var newText = $textInput.val();

    $('li:last').after('<li>' + newText + '</li>');

    $newItemForm.hide();

    $newItemButton.show();

    $textInput.val('');

  });


});

 

 

 

 

 

 

 

 

 

event 객체

모든 이벤트 처리 함수는 event 객체를 전달받는다.

이 객체는 발생한 이벤트와 관련된 메서드와 속성을 가지고 있다.


)

$(‘li’).on(‘click’,function(e){

eventType = e.type;

});


1.event 객체에 매개변수 이름을 지정한다.

2.함수 내에서 event 객체를 참조하기 위해 이 이름을 사용한다.

3. 익숙한 마침표 표기법을 이용하여 객체의 속성과 메서드를 사용한다.


속성

설명

type

이벤트의 종류

which

불려진 버튼이나 키

data

이벤트가 발생했을 때 함수에 전달된 추가 정보들을 가지고 있는 객체표현식

target

이벤트가 발생한 dom요소

pageX

뷰포트의 왼쪽 모서리로부터 마우스까지의 위치

pageY

뷰포트의 상단으로부터 마우스까지의 위치

timeStamp

 

 

메소드

설 명

.preventDefault()

기본 동작을 취소한다(품 데이터 전송)

.stopPropagation()

상위 객체로 이벤트가 버블링되는 것을 중단한다.

 

.html

<div id="page">

<h1 id="header">List</h1>

<h2>Buy groceries</h2>

<ul>

<li id="one" class="hot"><em>fresh</em> figs</li>

<li id="two" class="hot">pine nuts</li>

<li id="three" class="hot">honey</li>

<li id="four">balsamic vinegar</li>

</ul>

</div>


.js

$(function() {

$('li').on('click', function(e) {

$('li span').remove();

var date = new Date();

date.setTime(e.timeStamp);

var clicked = date.toDateString();

$(this).append('<span class="date">' + clicked + ' ' + e.type + '</span>');

});

});

1.<li>요소에 이미 존재하는 <span>요소들을 모두 제거한다.

2. 새로운 Date 객체를 생성하고 요소가 클릭되어 이벤트가 발생한 시간을 지정한다.

3. 이벤트가 클릭된 시간은 실제로 읽을 수 있는 문자열로 변환한다.

4. 목록 아이템이 클릭된 시간을 목록 아이템에 추가한다.(이벤트의 종류도 함께 출력한다.)

 


이벤트 핸들러의 추가 매개변수

.on() 메서드는 두 개의 선택적인 매개변수를 제공한다.

첫 번째 매개변수는 jQuery 객체집합에서 이벤트에 대응할 요소들을 필터링하기 위한 것이며

두 번째 매개변수는 객체 표현식을 이용하여 이벤트 핸들러에 전달할 추가 정보들을 위한 것이다.


.on(events[, select] [,data], function(e));


대응할 이벤트를 나열한다.(이벤트 이름을 공백으로 구분한다.)

일부요소만 이벤트를 대응하게 하려면 두 번째 셀렉터를 이용해서 자손 요소를 필터링 할 수 있다.

이벤트가 발생했을 때 호출될 함수에 추가 정보를 전달할 수 있다. 이 정보들은 이벤트 객체 e 와 함께 전달 된다.

특정이벤트가 발생했을 때 객체집합 내의 요소들을 대상으로 실행될 함수를 지정한다.

 

)

$(function() {

var listItem, itemStatus, eventType;

$('ul').on(

'click mouseover',

':not(#four)',

{status: 'important'},

function(e) {

listItem = 'Item: ' + e.target.textContent + '<br />';

itemStatus = 'Status: ' + e.data.status + '<br />';

eventType = 'Event: ' + e.type;

$('#notes').html(listItem + itemStatus + eventType);

}

);

});

 

1.click 이나 mouseover 이벤트가 발생하면 실행된다.

2. selector 매개변수는 id 특성 값이 four인 요소를 필터링 한다.

3. 객체표현식을 통해 추가 정보가 이벤트 핸들러에 전달된다.

4. 이벤트 핸들러는 event 객체를 이용하여 사용자가 선택한 요소의 콘텐츠와 함수에 전달된 데이터, 이벤트 종류등을 아래의 흰색 상자에 출력한다.

 

메서드

설명

.show()

선택된 아이템을 보이게 한다.

.hide()

선택된 아이템을 숨긴다.

.toggle()

선택된 아이템을 보이거나 숨기는 효과를 번갈아 적용한다.


효과

페이드 효과

메서드

설명

.fadeIn()

선택된 요소를 불투명하게 만들어 페이드인 효과 적용

.fadeOut()

선택된 요소를 투명하게 만들어 페이드아웃 효과 적용

.fadeTo()

선택된 요소의 불투명도 조절

.fadeToggle()

선택된 요소의 불투명도를 조정하여 현재 상태의 반대로 전환

 

슬라이딩 효과

메서드

설명

.slideUp()

선택된 아이템에 슬라이드 되어 사라지는 효과

.slideDown()

선택된 아이템에 슬라이드되어 나타나는 효과

.slideToggle()

선택된 요소에 현재 상태의 반대 상태로 전환

 임의효과

메서드

설명

.delay()

큐 내의 다음 아이템의 실행을 잠시 지연시킨다.

.stop()

현재 실행 중인 애니메이션을 중단한다.

.animate()

새로운 임의의 애니메이션을 생성한다.


)

.html

<body>

<div id="page">

<h1 id="header">List</h1>

<h2>Buy groceries</h2>

<ul>

<li id="one" class="hot"><em>fresh</em> figs</li>

<li id="two" class="hot">pine nuts</li>

<li id="three" class="hot">honey</li>

<li id="four">balsamic vinegar</li>

</ul>

</div>

 

.js

$(function() {

$('h2').hide().slideDown();

var $li = $('li');

$li.hide().each(function(index) {

$(this).delay(700 * index).fadeIn(700);

});

$li.on('click', function() {

$(this).fadeOut(700);

});

});

 

1.<h2> 요소를 선택한 후 나중에 애니메이션과 함께 나타날 수 있또록 우선 숨긴다. 제목을 보이게 하기 위해 선택한 효과는 .slideDown()메서드다.

2.아이템들이 페이드인 되기전 반드시 숨겨져야 한다. 이후 . each() 메서드를 이용해서 각 li 아이템에 대해 루프를 실행한다.

3. 익명함수 내에서는 index 속성이 마치 카운터 변수처럼 현재 동작 중인 li 요소를 가리키고 있다.

4. delay() 메서드는 목록 아이템이 나타나기 전에 약간의 지연을 만들어 낸다. 이때 지연될 시간은 인덱스 번호에 700밀리초를 곱하여 계산한다. 그렇지 않으면 아이템들이 모두 같은 시간에 나타난다.

 

 

css 속성에 애니메이션 적용하기

숫자로 표현될 수 있는 속성이라면 어떠한 속성이라도 애니메이션을 사용할 수 있다.

 

)

.animate({

// 변경할 스타일들을 나열한다.

}[,speed][,easing][, complete]);

 

1.speed 매개변수는 애니메잉션이 진행될 시간의 길이를 밀리초 단위로 지정하기 위한 것이다.

 

)

.html

<body>

<div id="page">

<h1 id="header">List</h1>

<h2>Buy groceries</h2>

<ul>

<li id="one" class="hot"><em>fresh</em> figs</li>

<li id="two" class="hot">pine nuts</li>

<li id="three" class="hot">honey</li>

<li id="four">balsamic vinegar</li>

</ul>

</div>


.js

$(function() {

$('li').on('click', function() {

$(this).animate({

opacity: 0.0,

paddingLeft: '+=80'

}, 500, function() {

$(this).remove();

});

});

});


DOM 탐색하기

jQuery 객체 집합을 생성하고 나면 이 페이지에서 소개하는 메서드들을 이용하여 기본 객체집합의 요소들과 관련된 다른 요소들에 접근할 수 있다.


셀렉터가 필요한 메서드들

메서드

설명

.find()

현재 객체집합에서 셀렉터와 일치하는 요소들을 리턴한다.

.closest()

셀렉터와 일치하는 가장 근접한 상위 요소(직계 부모무터 최상위 요소까지 모두 탐색한다.)


셀렉터가 선택적인 메서드들

메서드

설명

.parent()

현재 객체집합의 직계 부모 요소를 리턴한다.

.parents()

현재 객체집합의 모든 부모 요소를 리턴한다.

.children()

현재 객체집합의 모든 자식 요소를 리턴한다.

.siblings()

현재 객체집합의 모든 이웃 요소를 리턴한다.

.next()

현재 요소의 다음 이웃 요소를 리턴한다.

.nextAll()

현재 요소의 다음 이옷 요소들을 모두 리턴한다.

.prev()

현재 요소의 이전 이웃 요소를 리턴한다.

.prevAll()

현재 요소의 이전 이웃 요소들을 모두 리턴한다.


)

.html

<body>

<div id="page">

<h1 id="header">List</h1>

<h2>Buy groceries</h2>

<ul>

<li id="one" class="hot"><em>fresh</em> figs</li>

<li id="two" class="hot">pine nuts</li>

<li id="three" class="hot">honey</li>

<li id="four">balsamic vinegar</li>

</ul>

</div>

 

.js

$(function() {

var $h2 = $('h2');

$('ul').hide();

$h2.append('<a class="show">show</a>');

 

$h2.on('click', function() {

$h2.next('ul')

.fadeIn(500)

.children('.hot')

.addClass('complete');

$h2.find('a').fadeOut();

});

 

});

 

1.<h2>요소의 아무 곳이나 클릭하면 click 이벤트가 발생하여 익명 함수가 실행된다.

2. .next() 메서드를 이용하여 <h2> 요소의 바로 다음 이웃 요소인 <ul> 요소를 가져온다.

3. <ul> 요소에 페이드인 효과를 적용한다.

4. .children() 메서드를 이용하여 <ul> 요소의 모든 자식 요소들을 가져 온다. 이때 셀렉터를 이용하여 class 특성 값이 hot 인 자식 요소들만 가져오도록 한다.

5. addClass() 메서드를 이용하여 <li> 요소에 complete 라는 클래스 이름을 추가한다. 또한 이 코드는 메서드를 연결하여 호출함으로한 노드에서 다른 노드로 옮겨갈 수도 있다.

6. 마지막 단계에서는 .find() 메서드를 이용하여 <h2> 요소의 자식 요소인 <a> 요소를 찾는다. 이제 페이지에는 목록이 보이기 때문에 해당 요소가 계속해서 보일 필요가 없으므로 이 요소에 페이드아웃 효과를 적용하여 페이지에서 사라지도록 한다.

 

 

객체집합에 요소를 추가하거나 필터링하기

일단 jQuery 객체집합을 만들었다면 여기에 요소를 더 추가하거나 객체집합 내의 요소 중 일부만을 다루기 위해 필터를 적용할 수 있다.

 

객체집합에 요소 추가하기

메서드

설명

.add()

매개변수로 지정된 셀렉터에 의해 선택된 요소들을 기존 객체집합에 추가한다.

 

두 번째 셀렉터를 이용하여 필터링하기

메서드/셀렉터

설명

.filter()

두 번째 셀렉터와 일치하는 요소들을 찾아 리턴

.find()

셀렉터와 일치하는 하위 요소들을 찾아 리턴

.not() / :not()

셀렉터와 일치하지 않는 요소들을 리턴

.has() / :has()

셀렉터와 일치하는 하위 요소들을 가지고 있는 요소들을 리턴

:contains()

지정한 텍스트를 가진 모든 요소를 리턴

 

콘텐츠 테스트 하기

메서드

설명

.is()

현재 객체집합이 지정된 조건에 일치하는지를 검사한다.(불리언을 리턴)

 

.html

<div id="page">

<h1 id="header">List</h1>

<h2>Buy groceries</h2>

<ul>

<li id="one" class="hot"><em>fresh</em> figs</li>

<li id="two" class="hot">pine nuts</li>

<li id="three" class="hot">honey</li>

<li id="four">balsamic vinegar</li>

</ul>

</div>

<script src="js/jquery-1.11.0.js"></script>

<script src="js/filters.js"></script>

</body>


.js

$(function() {

var $listItems = $('li');

$listItems.filter('.hot:last').removeClass('hot');

$('li:not(.hot)').addClass('cool');

$listItems.has('em').addClass('complete');

$listItems.each(function() {

var $this = $(this);

if ($this.is('.hot')) {

$this.prepend('Priority item: ');

}

});

$('li:contains("honey")').append(' (local)');

});

 

.filter() 메서드를 이용하여 class 특성 값이 hot인 목록 아이템을 찾아낸다. 이후 그 값을 classs 특성에서 제거한다.

:not() 셀렉터를 이용하여 li 요소들 중 calss 특성값이 hot이 아닌 아이템들을 찾아낸 후 이 아이템들의 class 특성에 cool 이라는 값을 추가한다.

.has() 메서드를 이용하여 em 요소를 가진 li 요소를 찾아낸 후 그 요소의 class 특성에 complete라는 값을 추가한다.

.each() 메서드를 이용하여 목록 아이템에 대해 루프를 실행한다. 코드가 현재 참조하는 요소를 jQuery 객체에 캐시한 후 , .is() 메서드를 이용하여 li 요소의 class 특성 값이 hot 인지 여부를 확인 한다. 만일 그렇다면 우선 아이템: 이라는 문자열을 아이템의 앞 부분에 추가한다.

:contains 셀렉터를 이용하여 li 요소들 중 꿀이라는 텍스트를 가진 요소를 선택한후 국내산 이라는 문자열을 해당 아이템의 뒤에 덧붙인다.

 

아이템 순서대로 찾기

jQuery 셀렉터에 의해 리턴되는 각각의 아이템에는 인덱스 번호가 할당되며, 이 번호는 객체집합을 필터링할 때 사용할 수 있다.

 

인덱스 번호를 이용하여 요소 찾기

메서드/셀렉터

설명

.eq()

인덱스 번호에 해당하는 요소를 리턴한다.

:lt()

지정된 숫자보다 인덱스 번호가 작은 요소들을 리턴한다.

:gt()

지정된 숫자보다 인덱스 번호가 큰 요소들을 리턴한다.

 

)

$(function() {

$('li:lt(2)').removeClass('hot');

$('li').eq(0).addClass('complete');

$('li:gt(2)').addClass('cool');

});

 

셀렉터 내에서 :lt() 셀렉터를 이용하여 인덱스 번호가 2보다 작은 목록 아이템들을 찾는다. 그런 후 이 아이템들의 class 속성에서 hot 이라는 값을 제거한다.

.eq() 메서드를 이용하여 첫 번째 아이템을 선택 했다. 그런 후 class 특성에 complete 라는 값을 추가한다.

:gt() 셀렉터를 추가하여 인덱스 번호가 2 보다 큰 아이템들을 찾는다. 그리고 그 아이템들의 class 특성에 cool 이라는 값을 추가한다.

 


 

 

 

 

+ Recent posts

티스토리 툴바