JavaScriptμμ eval()μ λ체ν μ μλ λ°©λ²
JavaScriptμ eval()μ΄ μνν μ΄μ μ new Function()μΌλ‘ μμ νκ² λ체νλ λ°©λ²μ μ€μ©μ μΈ μμ μ ν¨κ» μμ보μΈμ. 보μκ³Ό μ±λ₯μ λͺ¨λ μ‘λ ν!
JavaScriptλ₯Ό μ¬μ©νλ€ λ³΄λ©΄ λ¬Έμμ΄λ‘ λ μ½λλ₯Ό μ€νν΄μΌ ν λκ° μμ΅λλ€. μ΄λ΄ λ κ°μ₯ λ¨Όμ λ μ€λ₯΄λ κ²μ΄ eval() ν¨μμ£ . νμ§λ§ eval()μ 보μ μ·¨μ½μ κ³Ό μ±λ₯ λ¬Έμ λ‘ μ
λͺ
μ΄ λμ΅λλ€.
μ΄ κΈμμλ eval()μ μνμ±μ μ΄ν΄λ³΄κ³ , λ μμ ν λμμΈ new Function()μ μ΄λ»κ² νμ©ν μ μλμ§ μ€μ©μ μΈ μμ μ ν¨κ» μμλ³΄κ² μ΅λλ€.
eval()μ΄λ 무μμΈκ°?
MDN λ¬Έμμ λ°λ₯΄λ©΄, eval()μ λ¬Έμμ΄λ‘ ννλ JavaScript μ½λλ₯Ό μ€ννλ ν¨μμ
λλ€. κ°λ¨ν μμ λ₯Ό ν΅ν΄ μλ λ°©μμ μ΄ν΄λ³ΌκΉμ?
let a = 3;
let b = 5;
eval('a += ' + b + ' + 2');
console.log(a); // 10
μ μ½λμμ eval()μ λ¬Έμμ΄ 'a += 5 + 2'λ₯Ό μ€μ JavaScript μ½λλ‘ μ€νν©λλ€. μΌν 보면 νΈλ¦¬ν΄ 보μ΄μ§λ§, μ΄ λ¨μν¨ λ€μλ μ¬κ°ν λ¬Έμ λ€μ΄ μ¨μ΄ μμ΄μ.
eval()μ 보μ μνμ±
eval()μ callerμ κΆνμΌλ‘ μ½λλ₯Ό μ€νν©λλ€. μ΄κ² λ¬΄μ¨ μλ―ΈμΌκΉμ? λ§μ½ μ¬μ©μ μ
λ ₯κ°μ eval()λ‘ μ€ννλ€λ©΄, μ
μμ μΈ μ½λκ° κ·Έλλ‘ μ€νλ μ μλ€λ λ»μ
λλ€.
var userContent = getUserInput(); // μ¬μ©μλ‘λΆν° μ
λ ₯λ°μ κ°
eval(userContent); // μν!
ν΄μ»€κ° "window.location = 'http://malicious-site.com'"μ κ°μ μ½λλ₯Ό μ
λ ₯νλ©΄ μ΄λ»κ² λ κΉμ? μ¬μ©μλ μ
μ± μ¬μ΄νΈλ‘ 리λ€μ΄λ νΈλκ±°λ, λ μ¬κ°ν κ²½μ° λ―Όκ°ν λ°μ΄ν°κ° νμ·¨λ μ μμ΅λλ€.
λν eval()μ νΈμΆλ μ€μ½ν(scope)μ μ§μ μ κ·Όν μ μμ΄μ. μ΄λ λ‘컬 λ³μλ₯Ό μ½κ±°λ μμ ν μ μλ€λ μλ―Έμ
λλ€:
function MyFunc() {
let secretToken = "abc123";
eval('console.log(secretToken); secretToken = "hacked";');
console.log(secretToken); // "hacked"
}
eval()μ μ±λ₯ λ¬Έμ
eval()μ JavaScript μΈν°ν리ν°λ₯Ό μ§μ νΈμΆνκΈ° λλ¬Έμ λ€λ₯Έ λμλ€λ³΄λ€ λ립λλ€. νλ JavaScript μμ§λ€μ μ½λλ₯Ό μ΅μ ννλλ°, eval()μ μ΄λ¬ν μ΅μ νλ₯Ό λ°©ν΄ν©λλ€. μμ§μ΄ μ΄λ€ μ½λκ° μ€νλ μ§ λ―Έλ¦¬ μ μ μκΈ° λλ¬Έμ΄μ£ .
new Function()μΌλ‘ λ μμ νκ²
new Function()μ eval()κ³Ό λΉμ·νκ² λ¬Έμμ΄λ‘λΆν° ν¨μλ₯Ό μμ±νμ§λ§, ν¨μ¬ λ μμ ν©λλ€. μ΄λ»κ² μ¬μ©νλμ§ μ΄ν΄λ³ΌκΉμ?
const add = new Function('a', 'b', 'return a + b');
console.log(add(2, 3)); // 5
λ¬Έλ²μ λ€μκ³Ό κ°μ΅λλ€:
let func = new Function([arg1, arg2, ...argN], functionBody);
μ¬κΈ°μ μ€μν μ μ new Function()μΌλ‘ μμ±λ ν¨μλ νμ μ μ μ€μ½νμμ μ€νλλ€λ κ²μ
λλ€. λ‘컬 λ³μμ μ κ·Όν μ μμ΄μ:
function MyFunc() {
let b = 123;
new Function('console.log(b);')(); // ReferenceError: b is not defined
}
μ΄λ° μ μ½μ΄ μ€νλ € 보μμ κ°νν©λλ€. μ μμ μΈ μ½λκ° ν¨μ λ΄λΆμ λ―Όκ°ν λ³μμ μ κ·Όνλ κ²μ μμ²μ μΌλ‘ μ°¨λ¨νλ κ±°μ£ .
eval()κ³Ό new Function() λΉκ΅νκΈ°
λ λ°©μμ ν΅μ¬ μ°¨μ΄μ μ μ 리ν΄λ³Όκ²μ.
μ€ν 컨ν μ€νΈμ μ€μ½ν
eval()μ νμ¬ μ€ν 컨ν
μ€νΈμμ μ½λλ₯Ό νκ°ν©λλ€:
function testEval() {
let x = 10;
eval('console.log(x); x = 20;');
console.log(x); // 20 - λ³μκ° μμ λ¨
}
testEval();
λ°λ©΄ new Function()μ μ μ 컨ν
μ€νΈμμλ§ μ€νλ©λλ€:
function testFunction() {
let x = 10;
const func = new Function('console.log(typeof x);'); // "undefined"
func();
console.log(x); // 10 - λ³μκ° μμ νκ² λ³΄νΈλ¨
}
testFunction();
보μμ±
new Function()μ μ νλ μ€μ½ν μ κ·Όμ 보μμ ν° μ₯μ μ
λλ€. λ‘컬 λ³μμ μ κ·Όν μ μμΌλ―λ‘, μ
μμ μΈ μ½λκ° μ€νλλλΌλ νΌν΄ λ²μκ° μ νμ μ΄μμ.
μ€μ μμ λ‘ λ°°μ°κΈ°
μ€μ λ‘ μ΄λ»κ² eval()μ new Function()μΌλ‘ λ체ν μ μμκΉμ?
κ°λ¨ν μμ κ³μ°
// eval() μ¬μ© (κΆμ₯νμ§ μμ)
const result1 = eval('2 + 3 * 4');
// new Function() μ¬μ© (κΆμ₯)
const calculate = new Function('return 2 + 3 * 4');
const result2 = calculate();
λμ ν¨μ μμ±
// μ¬μ©μκ° μ
λ ₯ν ν¨μ λ³Έλ¬ΈμΌλ‘ ν¨μ μμ±
const functionBody = 'return x * 2';
const double = new Function('x', functionBody);
console.log(double(5)); // 10
μΈλΆ λ³μ μμ νκ² μ λ¬νκΈ°
μ μ λ³μλ new Function()μμλ μ κ·Ό κ°λ₯νμ§λ§, λ μμ ν λ°©λ²μ λ§€κ°λ³μλ‘ λͺ
μμ μΌλ‘ μ λ¬νλ κ²μ
λλ€:
const multiplier = 3;
// λ§€κ°λ³μλ‘ λͺ
μμ μ λ¬
const multiply = new Function('x', 'multiplier', 'return x * multiplier');
console.log(multiply(5, multiplier)); // 15
JSON νμ± λμ
μ격ν JSONμ΄ μλ JavaScript κ°μ²΄ 리ν°λ΄μ νμ±ν λλ νμ©ν μ μμ΄μ:
function looseJsonParse(obj) {
return Function('"use strict";return (' + obj + ")")();
}
const result = looseJsonParse("{a:(4-1), b:function(){}, c:new Date()}");
console.log(result.a); // 3
μΈμ new Function()μ μ¬μ©ν΄μΌ ν κΉ?
new Function()μ΄ μ μ©ν μλ리μ€λ€μ μ΄ν΄λ³Όκ²μ:
λμ μ½λ μμ±
μ€μ νμΌμ΄λ μ¬μ©μ μ λ ₯μ κΈ°λ°μΌλ‘ ν¨μλ₯Ό λμ μΌλ‘ μμ±ν΄μΌ ν λ μ μ©ν©λλ€. μλ₯Ό λ€μ΄, μ¬μ©μ μ μ νν°λ μ λ ¬ λ‘μ§μ ꡬνν λμ£ .
μλλ°μ€ νκ²½
μ μ μ€μ½νμμλ§ μ€νλκΈ° λλ¬Έμ, νλ¬κ·ΈμΈ μμ€ν μ΄λ μ¬μ©μ μ€ν¬λ¦½νΈ μ€ν νκ²½μ λ§λ€ λ μ ν©ν©λλ€.
μ±λ₯μ΄ μ€μν κ²½μ°
λ°λ³΅μ μΌλ‘ μ€νλλ μ½λλΌλ©΄, ν λ² new Function()μΌλ‘ μ»΄νμΌν ν μ¬μ¬μ©νλ κ²μ΄ eval()μ λ§€λ² νΈμΆνλ κ²λ³΄λ€ ν¨μ¨μ μ
λλ€.
μ£Όμμ¬νκ³Ό νκ³
new Function()λ μλ²½ν ν΄κ²°μ±
μ μλλλ€. μ¬μ ν λ¬Έμμ΄λ‘λΆν° μ½λλ₯Ό μμ±νλ κ²μ΄λ―λ‘, μ λ’°ν μ μλ μ
λ ₯μ μ² μ ν κ²μ¦ν΄μΌ ν΄μ.
λν μΌλΆ μ£μ§ μΌμ΄μ€μμλ eval()μ΄λ new Function() λͺ¨λ μ ν©νμ§ μμ μ μμ΅λλ€. κ°λ₯νλ€λ©΄ λ€μκ³Ό κ°μ λμμ λ¨Όμ κ³ λ €ν΄λ³΄μΈμ:
κ°μ²΄ μμ± μ κ·Ό μ:
// eval() μ¬μ© (λμ¨)
const propName = 'username';
const value = eval('user.' + propName);
// λΈλΌμΌ νκΈ°λ² μ¬μ© (μ’μ)
const value = user[propName];
μ΄λ²€νΈ νΈλ€λ¬ λ±λ‘ μ:
// μΈλΌμΈ λ¬Έμμ΄ (λμ¨)
element.setAttribute("onclick", "handleClick()");
// μ΄λ²€νΈ 리μ€λ (μ’μ)
element.addEventListener("click", handleClick);
νμ΄λ¨Έ ν¨μ μ¬μ© μ:
// λ¬Έμμ΄ μ½λ (λμ¨)
setTimeout("console.log('Hello')", 1000);
// ν¨μ μ λ¬ (μ’μ)
setTimeout(() => console.log('Hello'), 1000);
λ μμ ν μ½λλ₯Ό ν₯ν΄
eval()μ νΈλ¦¬ν΄ 보μ΄μ§λ§, 보μκ³Ό μ±λ₯ μΈ‘λ©΄μμ μ¬κ°ν λ¬Έμ λ₯Ό μΌκΈ°ν μ μμ΅λλ€. new Function()μ μ μ μ€μ½ν μ νμ ν΅ν΄ μ΄λ¬ν μνμ ν¬κ² μ€μ¬μ£Όλ λ λμ λμμ΄μμ.
λ¬Όλ‘ κ°μ₯ μ’μ λ°©λ²μ λμ μ½λ μ€ν μ체λ₯Ό νΌνλ κ²μ
λλ€. νμ§λ§ λΆκ°νΌν μν©μ΄λΌλ©΄, new Function()μ μ ννλ μ
λ ₯κ° κ²μ¦μ μ² μ ν νλ κ²μ μμ§ λ§μΈμ.
보μμ ννν μ μλ μμμ λλ€. μ½λ ν μ€μ΄ μ 체 μ ν리μΌμ΄μ μ μμ μ μ’μ°ν μ μλ€λ μ μ νμ κΈ°μ΅νλ©΄μ κ°λ°νμκΈΈ λ°λλλ€ :)