Mixed Return Values

Mixed Return Values

In Stylus, a lightweight CSS preprocessor, handling complex logic often requires combining multiple features. Among them, "Mix" is a core feature that allows developers to combine multiple CSS properties for calculation and output. When we define a function or an object in a Stylus script and return multiple values, it involves "mixed return values."

Stylus's mixed return value mechanism is not simply array concatenation; rather, it refers to returning data of different types (such as strings, numbers, booleans, or CSS objects) simultaneously within an expression or statement. This enables subsequent template engines (like EJS, Mustache) to parse and render them separately. This feature significantly enhances Stylus's flexibility in handling dynamic style generation, allowing us to implement complex logic judgments and outputs without writing cumbersome intermediate variables.
Stylus supports several ways to construct mixed return values. The most common approach is using a chain of expressions separated by commas, or utilizing the return statement within functions combined with multi-line assignments.

In function definitions, you can directly list multiple return values:

// Example: Returning multiple values directly
function getStatus(name)
  return name is 'admin' ? true : false, name.length > 5 ? 'long' : 'short'

The above code returns both a boolean and a string simultaneously. In Stylus's parser, these values are treated as a tuple or list structure for the rendering engine to extract individually. Additionally, different line return values can be separated by semicolons, which is clearer in scenarios with more complex logic:

function calculatePrice(base, tax)
  discount = base * 0.1
  finalPrice = base + (base * tax) - discount
  return finalPrice, 'discounted'

Here, the function first calculates the discount amount and the final price, then returns a numeric value and a descriptive string. This structure makes the code logic more modular and easier to maintain.

Practical Application in Template Engines

The primary application scenario for mixed return values is in the interaction between Stylus and backend template engines. Many modern frontend projects use Stylus to generate CSS while rendering HTML content through engines like EJS or Mustache. In this case, Stylus scripts may need to return data for processing by the JS layer or directly embedded into reactive data streams.

Assume we have a user configuration object that needs to dynamically generate permission settings based on the user's role:

@require ejs

function getUserPermissions(role)
  canEdit = role is 'editor'
  canDelete = role is 'admin'
  
  // Mixed return: Permission status and corresponding message
  return 
    canEdit, canDelete ? 'Full Access' : 'Read Only', 
    {
      css: 'permission-' + (canDelete ? 'admin' : 'editor')
    }

In this example, the function returns three parts: two booleans, one string, and a CSS object. When this code is called by EJS, the rendering engine can access these return values separately to generate JSON data in the following format or use it directly within the template:

<% const { canEdit, canDelete, css } = getUserPermissions('<%= role %>'); %>
<div class="btn <%= css %>">权限:<%= canEdit ? '编辑' : '只读' %></div>

Best Practices and Precautions

In actual development, reasonably using mixed return values can significantly improve code readability and execution efficiency. However, due to the special parsing mechanism of Stylus, developers should pay attention to the following points:

  • Type Consistency: Although Stylus supports mixed-type returns, it is recommended to perform unified logical judgments within the function first to avoid undefined variables appearing in return values.
  • Readability First: When return values exceed two, it is recommended to wrap them using object literals or enhance semantics through named parameters to prevent callers from confusing the meanings of various values.
  • Performance Considerations: For frequently called functions, mixed returns increase parsing overhead. If only partial data is needed, consider splitting multiple small functions to improve performance.
// Recommended approach: Wrap complex return values with an object
function getComplexData(id)
  user = getUserById(id)
  return {
    isActive: user.status is 'active',
    role: user.role,
    badge: user.level > 3 ? 'vip' : 'normal'
  }

By mastering the usage of mixed return values, developers can more fluently build a combination of dynamic styles and business logic in Stylus, thereby creating frontend applications that are both beautiful and powerful.