Now.js Framework Documentation

Now.js Framework Documentation

ExpressionEvaluator

TH 04 Sep 2026 01:40

ExpressionEvaluator

ExpressionEvaluator Evaluates the small expression language used inside data attributes — data-if, data-attr, data-for and friends. It is a hand-written tokenizer plus shunting-yard parser rather than eval, so page markup can never execute arbitrary JavaScript. Two safety rules run through the whole file: - Property paths and function names are rejected when any segment is in dangerousKeys, which blocks prototype-chain traversal. - Values that cannot be represented as text safely are replaced by a ref token (REF_PREFIX + counter) held in _refs, and the token is never allowed to reach the rendered output.

หน้านี้สร้างจากซอร์สโดยตรงเมื่อ 2026-08-21 คำอธิบายมาจาก JSDoc ในไฟล์
รันซ้ำได้ด้วย docs_scaffold เมื่อโค้ดเปลี่ยน อย่าแก้ด้วยมือถ้าตั้งใจให้ generate ต่อ

ที่มา

  • ไฟล์: Now/js/ExpressionEvaluator.js (1176 บรรทัด)
  • รูปแบบ: ES class

เมธอดสาธารณะ (24)

static evaluate(expression, state, context)

Evaluate an expression against a state object. Recursion depth is tracked so nested evaluation cannot run away. Before returning, any ref token left in a string result is swapped back for its real value — a token must never be shown to the user.

static evaluatePostfix(postfix, state, context)

Evaluate a postfix token list. Operands are pushed on a stack and each operator pops its arity — one for !, two for everything else.

static getPropertyPath(path, state, context)

Read a dotted path out of state or context. Refuses the whole path when any segment is in dangerousKeys, so an expression cannot walk into __proto__ or constructor and reach the prototype chain.

static isPureBracketPath(expression)

True when the expression is a property path and nothing else — a['b'].c yes, a['b'] && c no · brackets may hold anything, what matters is that no operator sits outside them

static isRef(name)

Whether a string is a live ref token. Checks both the prefix and that the token is still registered, so text that merely looks like a token is not mistaken for one.

static isSimpleStringLiteral(expression)

Whether an expression is nothing more than a quoted string. Lets the caller skip tokenising and parsing when the expression is plain text in quotes.

static makeRef(value)

Store a value behind a ref token. Used for values that cannot survive a round trip through text — functions, objects, anything whose String() form would lose meaning. The token is a placeholder that only this class can resolve.

static parseArrayLiteral(expression, state, context)

Evaluate an array literal. Items are split at top level only, so a nested array or a comma inside a string stays in one piece, then each item is evaluated.

static parseObjectLiteral(expression, state, context)

Evaluate an object literal. Pairs are split at top level, then each is split into key and value by splitKeyValue so a colon inside a nested value is not mistaken for the separator.

static registerFunction(name, fn)

Make a function callable from expressions. Rejected when the name is not a plain dotted identifier, when any segment is in dangerousKeys, or when it would collide with the ref-token prefix.

static registerFunctions(map, prefix = '')

Register several functions at once. Entries that fail registerFunction are skipped rather than aborting the batch, so one bad name cannot block the rest.

static resolveBracketAccess(expression, state, context)

Resolve a[b] access, where the key is itself an expression. The path is split into property and bracket segments so topic[lng.value] evaluates lng.value first and uses the result as the key.

static resolveBracketKey(keyExpression, state, context)

Work out the key inside a bracket. The inner expression is evaluated first; when that yields nothing usable the raw text is treated as a literal key instead.

static resolveCallee(name, state, context)

Resolve the function an expression is trying to call. Blocks dangerous key segments, and when the name is a ref token only resolves it if the stored value really is a function.

static resolveInterpolation(expression, state, context)

Pre-process mustache interpolations within an expression string. Resolves {{expr}} patterns innermost-first, replacing each with its evaluated literal value so the outer expression can proceed. Examples: "topic[{{lng.value}}]" → "topic['th']" (string result wrapped in quotes) "items[{{index}}]" → "items[2]" (numeric result kept bare)

static resolveParenthesizedExpressions(expression, state, context)

Evaluate innermost parentheses first, replacing each with its result. Loops until no parentheses remain, with a safety counter so a malformed expression cannot spin forever.

static splitCallArgs(argsStr)

Split a call's argument list. Quote state respects backslash escapes, so an escaped quote inside a string argument does not end the string early.

static splitKeyValue(pair)

Split one object-literal pair into key and value at the top-level colon. Quotes and every kind of bracket are tracked, so a colon inside a nested object, array or string is not treated as the separator.

static splitTernary(expression)

Split a ternary expression into condition, trueExpr, falseExpr Handles nested ternary and strings containing ? or : safely

static splitTopLevel(input, delimiter)

Split on a delimiter, ignoring ones nested inside quotes or brackets.

static toExpressionLiteral(value)

Render a value back into expression source. Used when a resolved value must be substituted into the expression text before the next parsing pass; strings come back quoted and escaped.

static toPostfix(tokens)

Convert infix tokens to postfix using shunting-yard. Precedence runs ! above * / %, above + -, above the comparisons, with the logical operators lowest, matching JavaScript closely enough for the expressions data attributes actually contain.

static toSubstitution(value)

Only round-trip values ​​are safe to use as text, the rest use ref.

static tokenize(expression)

Split an expression into tokens. Quotes, brackets and parentheses are tracked so an operator inside a string literal is not mistaken for a real operator.

พึ่งพาคลาสอื่น

ErrorManager · Utils