uncaught ReferenceError: $ is not defined

 

html에서 잘 작동하던 js파일이 jsp 파일에 적용하려니깐 잘 작동하지 않았다.😤

 

무슨 문제인 것인가 찾아 보는 와중 console.log로 scroll의 위치를 찍은 결과 이동을 해도 0이 나오는 것이었다.

 

/*------- 마우스 스크롤 -------*/
window.addEventListener('scroll',function(){
	//let currScroll = document.body.scrollTop; 
    let currScroll = document.documentElement.scrollTop; // 현재 스크롤바 위치
    let _web_about_img1 = $('.web_about > img:nth-child(1)'); // img 태그
    let _web_about_img2 = $('.web_about > img:nth-child(2)');
    let _web_about_img3 = $('.web_about > img:nth-child(3)');
    let _web_about_info = $('.web_about_info');
    console.log(currScroll);

    if(currScroll > 800){
   		// 800 보다 위
    }

    if(currScroll < 500){
    	// 500 보다 아래
    }
});

 

😡분명 document.documentElement.scrollTop; 을 사용했을 때는 html에서도 scroll의 위치가 0으로 나왔다.

 

※ 에러가 나오면 js코드 위치를 의심해 볼 것!

uncaught ReferenceError: $ is not defined

의 구문이 이상한 곳에서 뜨면서 scroll의 위치를 잡지 못하는 거였다..

 

처음에는 window.addEventListener부분이 윈도우를 실행하면 실행되는 함수인데

혹시 파싱이 html이 끝나지 않았는데 js가 피칭이 되어서 오류가 난 것은 아닐까?라는 생각을 해봤지만 그건 아니었다.

 

html에 document.body를 적용했을 때는 값이 잘 나왔다.

하지만 document.element는 나오지 않았다. why? IE, firefox 등등만 지원한다고 한다.

body를 사용해야지만 Chrome, safari 등등에서 사용 가능하다고 했기 때문이다.

 

근데 JSP파일에 document.documentElement를 사용한 결과 JSP 파일에서 정상 동작을 하였다..

 

document.documentElement최상위 <html> 요소를 가리키고,

document.body는 <body> 의 요소를 가리킨다.

사용 방법

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

<script defer src="/js/index.js"></script>

<script async src="/js/index.js"></script>

script

Just script만 설정해주면 parsing HTML feching js executing js 식으로 실행되는데

 

단점은 사용자가 기본적인 html을 빨리 볼 수 있는데, javascript에 의존적이면 js가 늦게 들어와서

 

피칭하는 시간(실행 시간)을 기다려야 한다.


async

async, asyn 으로 설정해주면 html을 파시당하다가 병렬로 asyn을 확인하고, 다운로드하자 해놓고 다운로드가

 

다 되면 다시 실행주는 방식으로 피칭하는 시간을 아낄 수는 있지만, html이 되면서 js가 실행되기 때문에

 

html이 중간만 뿌려지는 상태에서 js가 뿌려질 수 있음

 


defer

내가 생각하기에 제일 깔끔한 방법(?) 인 것 같고, html 파일을 다 파싱 해주고 그다음에 js를 실행시키는 방법이다.

 

asyn는 순서에 상관없이 다운로드가 빨리 된 것 부터 피칭이 되기 때문에 defer을 이용하면 순서대로 할 수 있어서

 

defer을 쓰는 것이 좋은 것 같다.

Function

- 여러번 재사용이 가능한 함수

- 어떠한 값을 계산하기 위해 사용

- 하나의 함수는 한 가지의 일만 할 수 있음!

'use strict';
//Function
//hi를 불러오는 함수를 만들어 보겠습니다.
function printHi(){
    console.log('Hi');
}
printHi(); // 이렇게 하면 Hi만 나오기 때문에 쓸모가 없음..
// 그래서 파라미터를 받아서 찍어줘야 한다.

function log(message){
    console.log(message);
}
//자바스크립트에서는 타입이 없기 때문에 명확하지가 않다.. string인지.. num인지
log('hihi');
log(1234);

타입이 없으므로 큰 프로젝트에서는 타입이 중요하므로 TypeScript를 사용해주는 것이 좋다.

 

해당 링크로 이동하면 Plyground로 가보면 TypeScript를 이용해서 코드를 작성하면 JavaScript로 어떻게 나타내는지 알려 준다.

TypeScript는 String을 받아서 : number을 이용해서 num타입 형태로 내보낼 수 있음.


Parameters(파라미터)

// Parameters 매개변수
// 오브젝트는 레퍼런스로 전달 됨.
function changeName(obj){
    obj.name = 'coder';
}
const kaki = { name: 'kaki'};
changeName(kaki);
console.log(kaki);

오브젝트가 만들어진 레퍼런스가 메모리에 들어감 

changeName을 사용하게 되면 kaki가 가리키고있는 레퍼런스의 name값을 coder로 변경하는 코드.


Default Parameters

// Default paramters
function showMessage(message, from){
    console.log(`${message} by ${from}`);
}
showMessage('Hi!');

showMessage를 통해서 message, from 두개의 파라미터를 보내야 하는데

Hi!인 하나의 파라미터 값만 보내면 console에는 ${from} 쪽에 undefined가 뜨는것을 확인할 수 있다.


Rest Parameters

// Rest parameters
function printAll(...hmmm){
    for(let i=0; i<hmmm.length; i++){
        console.log(hmmm[i]);
    }
    
    for(const arg of args){
    	console.log(arg);
    }
}
printAll('dream','coding','fighting');

...을 이용하면 배열형태로 전달된다.

인자를 3개를 전달하면

3개의 인자가 console에 찍히는 것을 확인할 수 있다.


Return

// return
function sum(a,b){
    return a+b;
}
const result = sum(1,2); // 3
console.log(`sum: ${sum(1,2)}`);

값을 리턴할 수 있고, return문 이없는 코드는 return undefined가 생략되어 있다고 생각하면 된다.


Anonymous Function

// 익명 함수 anonymous function
const print = function(){
    console.log('print');
};
print();

함수를 선언함과 동시에 바로 print라는 변수에 할당할 수 있음. 이렇게 이름이 없으면 어나니머스 펑션이라고 부름.


Callback hell

// Callback function
function randomQuiz(answer, printYes, printNo){
    if(answer === 'love you'){
        printYes();
    }else{
        printNo();
    }
}

// anonymous function
const printYes = function(){
    console.log('yes!');
}

// named function
const printNo = function print(){
    console.log('no!');
};
randomQuiz('wrong',printYes,printNo);
randomQuiz('love you',printYes,printNo);

랜덤퀴즈는 파라미터로 answer, 함수yes, 함수no를 받고있음.

이렇게 상황에 맞으면 이 함수를 부르라는 뜻으로 맞으면 printYes 함수를 부르고, 틀리면 printNo 함수를 부른다.

 

printYes는 위의 익명함수를 이용해서 console에 나오도록 하고 있고,

printNo는 print라는 이름을 줘서 named function으로 사용하고 있음.

named function을 사용하는 이유는 디버깅 할 때 이용하기 위해서임.


Arrow function🎈

// Arrow function
// always anonymous 항상 이름이 없음.
const simplePrint = function(){
    console.log('simplePrint!');
};

const simplePrint = () => console.log('simplePrint');
const add = (a, b) => a + b;

자바의 람다식처럼 간편하게 쓸 수 있음.

string concatenation 

문자열 결합

// String concatenation
console.log('제니의'+' 하루');
console.log('1'+2);
console.log(`string literals: 1 + 2 = ${1+2}`);

console값을 보면

제니의 하루 , 12 , string literals: 1 + 2 = 3이 출력되는 것을 확인할 수 있음.


숫자 연산

// numeric(숫자) operators(연산자)
console.log(1 + 1); // 더하기 
console.log(1 - 1); // 빼기 
console.log(1 / 1); // 나누기
console.log(1 * 1); // 곱하기
console.log(5 % 2); // 나머지
console.log(2 ** 3); // 제곱
// 결과 : 2 0 1 1 1 8

증감 연산자 , 할당

// Increment and decrement operators
let counter = 2;
const preIncrement = ++counter; // 이게 preIncrement임 하나증가해서 3이 됨.
// 할당하는 연산자
let x = 3;
let y = 6;
x += y; // 생략 가능 x = x+y 
x -= y;
x *= y;
x /= y;

|| (or) , && (and) , ! (not) 

logical operators라고 한다.

const value1 = false;
const value2 = 4 < 2; // false

console.log(`or: ${value1 || value2 || check()}`);
//console.log(`or: ${value1 && value2 && check()}`);

// check 함수
function check() {
    for(let i=0; i < 10; i++){
        //wasting time
        console.log('ㅇㅅㅇ');
    }
    return true;
}

check는 10까지 ㅇㅅㅇ찍어주고 결국 true를 반환

 

그러면 false, false, true이므로 true를 반환해줌

 

만약에 처음에 value1이 true가 나오면 나머지를 확인 안 하고 바로 true를 반환.

 

이 코드에서 또 주목할 점은 check() 함수가 맨 뒤에 있다는 점이다.

 

check() 함수는 연산이 많으므로 마지막에 검사하는 것이 프로그램 효율성에 좋다! (간단한 연산을 앞으로)

 

and(&&) 는 이미 맨 앞에서 false를 반환했으므로 나머지 검사를 안 해봐도 된다.

 


Equality

const stringF = '5';
const numberF = 5;

// == 타입을 변경해서 비교를 해 줌.
console.log(stringF == numberF); // true
console.log(stringF != numberF); // false

// === 타입까지 비교
console.log(stringF === numberF); // false
console.log(stringF !== numberF); // true

오브젝트를 비교하면 어떻게 될까 오브젝트는 reference에 탑재되어 저장됨.

const kaki1 = {name: 'kaki'};
const kaki2 = {name: 'kaki'};
const kaki3 = kaki1;

console.log(kaki1 == kaki2);
console.log(kaki1 === kaki2);
console.log(kaki1 === kaki3);

과연 어떻게 나올까요? 처음 콘솔은 값이 같아서 true라고 생각했지만 다른 레퍼런스에 객체가 저장되기 때문에 false가 나오고

두 번째도 레퍼런스가 달라서 false 마지막은 같은 레퍼런스를 가리키고 있으므로 true 가 나온것을 볼 수 있음.

 

예제 문제 생각해보기

// eqaulity - puzzler
console.log(0 == false);
console.log(0 === false);
console.log('' == false);
console.log('' === false);
console.log(null == undefined);
console.log(null === undefined);

false , false , false, false , true , false

true , false , true , false , true , false

0 하고 ''은 false로 간주될 수 있으므로 true이다. 하지만 타입은 같지 않음 그래서 ===로 비교하면 false

 

반복문은 생략하겠습니다.

'use strict'

// ES 5 에 추가되었다 , 상단에 정의
// 이것을 사용하면 정의하지 않은 변수를 쓰면 오류가 안났는데, console에 오류가 나오게 해줍니다.
'use strict'

상단에 'use strict'을 적어두고 시작한다. 좀 더 모던한 개발을 할 수 있음.


Variable ( 변수 )

// 2. Variable (변수)
// let (ES6에 추가되었음.)
let name = '승현';
console.log(name);
name = 'hello';
console.log(name);

변수는 계속해서 변하기 때문에 name을 호출하면 hello가 찍히는 것을 볼 수 있음.

// 2. Variable (변수)
// let (ES6에 추가되었음.)
let globalName = 'kaki';
{
let name = '승현';
console.log(name);
name = 'hello';
console.log(name);
}
console.log(name);
console.log(globalName);

이것은 {} 블록으로 scope를 설정해줬다 그러면 밖에서 console.log가 접근할 수 없어서 아무 값도 보이지 않지만

globalName은 밖에 선언돼있기 때문에 콘솔에 찍히는 것을 확인할 수 있음.

글로벌 변수는 프로그램이 시작하면서 끝날 때까지 탑재되어 있기 때문에 최소한으로 쓰는 것이 프로그램 효율에 좋다.

var는 절대 쓰지마 ! why ???

// var 쓰지마 !
// 값을 할당하기도 전에 console로 찍을수도 있고 값을 할당할 수 있음.. 
// var hoisting
// 블럭을 무시한다 , 블럭을 선언하면 깊은 곳은 접근을 하지 못하는데 var는 그냥 접근함 ..
console.log(age);
age = 4;
var age;

선언은 마지막에 했는데 그전에 쓸 수 있음.. 쓰면 안 됨!

이것이 바로 hoisting임!

hoisting?

어디에 선언했는지 상관없이 맨 위로 끌어올려주는 것을 말합니다.

이게 파일 맨 위로 올라가서 선언해준다..


const

// constants
const daysInWeek = 7;
const maxNumber = 5;

const를 사용하면 좋은 점 , 일단 let은 변하는 값! const는 불변의 값!이라고 생각하면 된다.

- 값이 안 바뀌어서 보안상에도 좋다.. 해커들이 값을 바꾸지 못함.

- 스레드들이 실행하면서 동시에 값을 변경하는데 변하지 않는다. 동시에 실행되면 값이 바뀔 수도 있는데 그럴 가능성이 줄어든다(?)

- 개발자가 실수하는 것을 방지해준다.


Variable Types

자바는 int , short , long처럼 숫자형에 타입이 있는데

자바스크립트에서는 num이라는 타입이 있어서 이거 하나로 해결된다. let a = 1.2 이런 식으로도 선언 가능

// Variable Types
const count = 17; // integer (정수형)
const size = 17.1; // decimal number (소수)
console.log(`value: ${count}, type: ${typeof count}`);
console.log(`value: ${size}, type: ${typeof size}`);

값에 상관없이 type이 number라는 것을 확인할 수 있다.

 

// number - special numeric values : 무한대에 수렴, 마이너스 무한대에 수렴 , 문자는 숫자로 못나눔
const infinity = 1 / 0;
const negativeInfinity = -1 / 0;
const nAn = 'not a number' / 2;
console.log(infinity);
console.log(negativeInfinity);
console.log(nAn);

특별한 숫자의 값

 

// bigInt라는 타입 추가되었음
const bigInt = 1234567890123456789012345678901234567890n; // over (-2 53승) ~ 2*53)
console.log(`value: ${bigInt}, type: ${typeof bigInt}`);
Number.MAX_SAFE_INTEGER;

마지막에 n 붙이면 타입이 bigint로 된다.


String

// string
const char = 'c';
const brendan = 'brendan';
const greeting = 'hello' + brendan;
console.log(`value: ${greeting}, type: ${typeof greeting}`);
const helloBob = `hi ${brendan}!`;
console.log(`value: ${helloBob}, type: ${typeof helloBob}`);

자바는 char , String 나눠서 있는데 그냥 string 하나로 쓸 수 있음

`(백 틱)을 이용하면 중간에 ${}을 이용해서 문자열들이 그대로 나올 수 있어서 좋다.


Boolean

// boolean
// 거짓(false) : 0 , null , undefined , NaN , ''
// 참(true) : 값
const canRead = true;
const test = 3 < 1;
console.log(`value : ${canRead}, type: ${typeof canRead}`);
console.log(`value : ${test}, type: ${typeof test}`);

타입이 boolean이고 canRead는 true test는 false로 나온 것을 확인할 수 있다.

null 과 undefined

// null
let nothing = null;
console.log(`value : ${nothing}, type: ${typeof nothing}`);

// undefined
let x;
console.log(`value : ${x}, type: ${typeof x}`);

null은 비어있는 상태 undefined는 아직 할당되지 않은 상태


Dynamic typing

// Dynamic typing : dynamically typed language
let text ='hello';
console.log(`value: ${text} , type: ${typeof text}`);
text = 1;
console.log(`value: ${text} , type: ${typeof text}`);
text = '7' + 5;
console.log(`value: ${text} , type: ${typeof text}`);
text = '8' / '2';
console.log(`value: ${text} , type: ${typeof text}`);

자바스크립트는 다이나믹한게 hello로 선언을 했으면 일단 type이 string으로 나오고

1로 변경을 하면 number형으로 변환됩니다

string 7 하고 num형 5를 더하게 되면? 문자형인 75로 답이 나오게 됩니다.

string 8 하고 string 2를 나누게 되면.. 숫자형으로 인식하고 4로 나오게 됩니다!

 

let text ='hello';
console.log(text.charAt(0)); // h

text = '8' / '2';
console.log(text.charAt(0));

이렇게 실행하게 되면

에러가 발생하게 됩니다.

runtime에서 타입이 정해지기 때문에 이것 때문에 에러가 발생하는 이유가 많음. 이거 때문에 TS(Type Script)가 나왔음!

 

 

+ Recent posts