TNS
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
NEW! Try Stackie AI
CI/CD / JavaScript

JavaScript Kung Fu: Elegant Techniques To Master the Language

Whether you’re building enterprise software or just honing your skills, these patterns will help you write cleaner, faster and more maintainable code.
Jun 12th, 2025 7:00am by
Featued image for: JavaScript Kung Fu: Elegant Techniques To Master the Language
Image from luceluce on Shutterstock.

JavaScript isn’t just a language — it’s a specialized craft. And like any skilled martial art, the difference between being a novice and a master lies in the techniques you perfect. Anyone can write code that works, but writing code that’s clean, powerful and elegantly expressive is where true JavaScript Kung Fu begins.

Let’s deep dive into elevated JavaScript techniques that will make your code stand out from the crowd. It doesn’t matter if you’re building enterprise software or just sharpening your skills, these patterns will help you write cleaner, faster and more maintainable code — the kind that will make your future self (and teammates) nod with respect.

We’ll cover everything from:

  • Smart console.log practices that go beyond the basics
  • Using ES6 features like template literals, destructuring and spread operators for clearer, more intuitive logic
  • Writing more expressive conditionals with short-circuit evaluation
  • Using tools like console.table() and console.time() for debugging and performance profiling
  • And combining arrays like a boss, even with duplicates

Think of this as your dojo for modern JavaScript mastery. You’ve got the basics, but you’re ready to take it up a level.

Let’s code like a sensei.

1. Console.log Techniques: Logging Like a Pro

In the early stages of JavaScript development, many developers rely heavily on basic console.log() statements. While it gets the job done, advanced developers know there are far more powerful and cleaner ways to log data, especially when working with structured objects, debugging or profiling performance. Consider this simple example:

Basic Logging (Harder to Read)


While this works, it’s harder to distinguish between the logs, especially when dealing with multiple variables. Now, let’s explore cleaner alternatives.

2. Computed Property Logging

Instead of logging variables one by one, you can use shorthand object property names to group your logs into a single object, making them more readable:


Now the log is self-explanatory, clear and easier to inspect — perfect for debugging or reviewing nested data structures.

3. Custom Styling With %c

For UI-focused logs or when you want to highlight something specific in the console, you can use the %c directive along with CSS styles:


This is especially useful in large applications where you need to visually separate logs from one another, such as highlighting warnings, steps or critical state updates.

4. Displaying Objects in a Table With console.table()

When dealing with arrays of objects (or even a single object with multiple similar keys), console.table() is a visually superior alternative:


This logs a structured table with rows and columns, making it easy to scan and compare values. It’s ideal when you’re working with datasets like API responses, lists of users or status objects.

5. Benchmarking With console.time() and console.timeEnd()

Performance profiling is critical in JavaScript, especially when loops or operations may impact responsiveness. Use console.time() and console.timeEnd() to measure execution time:


This gives you insight into how long your logic takes to execute, helping with optimization decisions or detecting bottlenecks in your code.

By mastering these enhanced logging techniques, you’re not just printing data — you’re communicating intent, improving readability and debugging smarter. These tools are part of your JavaScript utility belt, helping you become more efficient, organized and effective in your development workflow.

Template Literals: Writing Strings With Superpowers

Gone are the days of messy string concatenation using the + operator. With template literals, introduced in ES6, JavaScript gives you a cleaner, more expressive way to build strings, especially when variables and expressions are involved. Template literals are enclosed in backticks instead of single or double quotes, and they support interpolation, multiline strings and even embedded expressions.

Let’s break it down:


Instead of writing:

'My name is ' + name + ' and I am ' + age + ' years old.'

Template literals let you inject variables directly into your string using ${}. This not only reduces clutter but also boosts readability and maintainability.


Previously, you’d have to use \n or concatenate lines awkwardly. With backticks, you just write across lines naturally.


You can even call functions inside:


Template literals make your code more expressive and cleaner, especially in scenarios involving dynamic data, API responses or logging. Whether you’re crafting UI messages, generating reports or debugging output, this feature adds elegance and power to your strings.

Using reduce() To Get Totals: From Clunky Loops To Clean Logic

When working with arrays of numbers or objects, it’s common to calculate a total, be it prices, scores or item quantities. Many developers fall into the trap of using verbose forloops or forEach() to accomplish this. While those methods work, they’re often less expressive and harder to maintain. The reduce() method offers a powerful and elegant alternative that not only condenses your code but also enhances its readability and intent.


This approach works, but it’s verbose, especially in large codebases. You’re manually managing the total, which can lead to errors and side effects.


Here’s why reduce() is superior:

  • acc (accumulator) starts at 0 (the second argument of reduce()).
  • On each iteration, it adds curr.price to acc.
  • After the loop finishes, you get the final total — clean, functional and declarative.

You can even make it more expressive with arrow functions and default values:


This version uses destructuring to directly access the price of each item, making the code more readable.

So next time you’re summing values in an array, ditch the loop and reach for reduce(). It’s the functional way to write logic that’s not just correct, but clean and powerful.

Understanding the Spread Operator and Array Merging

The spread operator (…) is one of the most elegant and versatile features introduced in ES6. It allows you to “spread” the elements of an iterable (like arrays or objects) into individual elements. This comes in handy especially when merging arrays, cloning or passing multiple values in a function call.

Basic Array Merging (Clean and Modern Way)

Let’s say you have two arrays:


Here’s the old-school approach using concat():


This works, but it’s a bit verbose and less readable compared to modern syntax.

And here’s the modern approach using the spread operator:


The new method is much cleaner, more expressive and easier to understand. You’re literally just saying: “Spread the values of arr1 and arr2 into one new array.”

In case of duplicates, merge with Set and the spread operator.

Let’s assume the arrays have duplicate values:


If we merge them directly:


We now have duplicate values. In many cases (like IDs, tags, etc.), we want unique values.

So to remove the duplicate values, we can use Set and the spread operator.


To give you context, Set is a built-in object that only stores unique values. We first use […] to merge the arrays. We then wrap it with new Set(...) to filter out duplicates, and finally, we spread that back into a new array.

Cloning an Array With Spread

If you ever want to copy an array without modifying the original, use the spread operator:

Understanding the Relevance of the Rest Operator

The rest operator (…) looks exactly like the spread operator, but it works in the opposite way. While the spread operator expands items, the rest operator gathers items into a single array or object.

It’s used mainly in:

  1. Function arguments
  2. Array destructuring
  3. Object destructuring

1. Rest in Function Parameters

Sometimes, you don’t know how many arguments a function will receive. Instead of listing them manually, use the rest operator to bundle them up.


Explanation:

  • ...numbers collects all the passed arguments into an array.
  • You can then manipulate that array like normal (such as using .reduce() to add them up).

2. Rest in Array Destructuring

The rest operator is handy when you want to get some values individually and gather the rest.


Explanation:

  • The first two values are extracted.
  • The rest operator gathers everything else into a new array, others.

3. Rest in Object Destructuring

You can also extract specific properties from an object and collect the remaining ones.


Explanation:

We pull out the name property.

The rest operator collects the remaining key-value pairs into rest.

While the rest (…) and spread (…) operators look identical in syntax, their behavior and purpose are fundamentally different. The spread operator is used to expand an array or object into individual elements or properties. You’ll typically see it used when passing arguments into a function or when combining arrays and objects. In contrast, the rest operator does the opposite. It’s used to gather multiple values into a single array or object. It’s commonly applied in function parameters to accept an indefinite number of arguments or in destructuring to collect remaining values. Think of it this way: Spread expands outward, breaking structures apart, while rest gathers inward, bundling them together. This subtle yet powerful distinction is key to writing flexible and clean JavaScript code.

Understanding Object Data Extraction in JavaScript

In JavaScript, object destructuring is a shorthand syntax that allows you to pull out properties from objects (or elements from arrays) into standalone variables. This makes your code cleaner and reduces redundancy.

Let’s take a basic object:


Traditional Way (Less Elegant)

If you want to access values, you’d typically do:


While this works just fine, it can become verbose or repetitive, especially when you need to reference the same property multiple times.

Now Let’s Use Destructuring for Cleaner Code

Instead of repeatedly writing me.age, you can destructure like this:


You can also extract multiple properties at once:

Destructuring With Arrays Inside Objects

Since likes is an array, we can destructure it, too:


Notice how we used an alias. We didn’t extract the likes array itself, but instead unpacked its elements directly into first and second.

Nullish Coalescing (??)

The nullish coalescing operator (??) is used to provide a default value when a variable is null or undefined. It’s especially useful when you want to fall back only for truly “empty” values and not for falsy values like 0, '' or false.

Without nullish coalescing:


With nullish coalescing:


Explanation:

  • || falls back for any falsy value (0, false, '', null, undefined).
  • ?? falls back only for null or undefined.

Converting Strings to Integers Using the + Sign

In JavaScript, the unary plus (+) operator can be used to quickly convert strings into numbers.

Traditional method:


Shorthand using +:


This is a quick and readable trick when you’re sure the string contains a valid number. If it doesn’t, the result will be NaN.

See the code below:

Optional Chaining (?.)

Optional chaining lets you safely access deeply nested object properties without having to check if each level exists. If the reference is null or undefined, it returns undefined instead of throwing an error.

Without optional chaining:


With optional chaining:


You can also use it with functions:


This is great for handling data from APIs** where some fields may be missing.

The Ternary Operator

The ternary operator is a shorthand for if/else. It follows this syntax:


To give you context, see the code below:


This is equivalent to:

Using || for Defaults

The logical OR (||) operator can be used to assign default values if the left-hand side is falsy:

Logical Short-Circuiting

JavaScript also allows you to write short if statements without else using the && operator.

condition && expression;

For example:


It only prints if isLoggedIn is true. Equivalent to:

Conclusion

Mastering JavaScript is about writing code that’s elegant, efficient and expressive. These techniques, from smarter console.log() practices and template literals to the subtle power of destructuring, spread/rest operators and short conditional logic will help you elevate your code from functional to formidable.

Think of these patterns as tools in your martial arts belt, with each one sharpening your ability to write cleaner, faster and more maintainable code. Whether you’re debugging like a pro with console.table() and console.time(), or merging arrays with surgical precision, every skill you build makes your JavaScript Kung Fu stronger.

Now go forth and code like a sensei. Your future self and your teammates will thank you for it.

Want to dive deeper into the possibilities of working with JavaScript? Read Andela’s full guide “Mastering JavaScript Proxies and Reflect for Real-World Use.”

Group Created with Sketch.
TNS owner Insight Partners is an investor in: Real.
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.