Fundamentals 14 min read

Understanding Programming Paradigms: Imperative, Declarative, Functional, and Object‑Oriented in JavaScript

This article explains core programming paradigms—imperative, declarative, functional, and object‑oriented—illustrating their concepts, differences, and practical JavaScript examples, while discussing features like first‑class functions, currying, composition, and OOP principles such as encapsulation, inheritance, and polymorphism.

政采云技术
政采云技术
政采云技术
Understanding Programming Paradigms: Imperative, Declarative, Functional, and Object‑Oriented in JavaScript

Programming paradigms define typical styles of writing software. This article introduces imperative, declarative, functional, and object‑oriented paradigms, especially in the context of JavaScript.

Imperative Programming

Imperative programming describes step‑by‑step instructions for the computer. The following example shows how to create a new array, iterate over a collection of people, and push names of those older than 35 into the new array.

const people = [
    { name: 'Lily', age: 33 },
    { name: 'Abby', age: 36 },
    { name: 'Mary', age: 32 },
    { name: 'Joyce', age: 35 },
    { name: 'Bella', age: 38 },
    { name: 'Stella', age: 40 },
  ];
  const newArry = [];
  for (let i = 0; i < people.length; i++) {
    if (people[i].age > 35) {
      newArry.push(people[i].name);
    }
  }

Advantages of imperative code are its straightforwardness and high performance; disadvantages include reliance on mutable state, many external variables, and lower readability.

Declarative Programming

Declarative programming states what should be done without describing how. The same filtering task can be expressed with Array.filter :

const peopleAgeFilter = (people) => {
return people.filter((item) => item.age > 35)
}

Declarative code reduces side effects, makes programs safer, and is well‑suited for high‑concurrency scenarios, though it may introduce performance overhead due to extra abstraction.

Functional Programming

In functional programming, functions are first‑class citizens and are treated as pure mappings from inputs to a single output. Key characteristics include first‑class functions, lazy evaluation, and absence of side effects. The article also covers currying and function composition.

// js 中的 function
function fun(data, value, type) {
  // 逻辑代码
}
y=f(x)

Currying transforms a multi‑parameter function into a chain of single‑parameter functions:

f(x, y, z) -> f(x)(y)(z)

Example of a curried square‑sum function:

// 原始版本
const squares = function(x, y) {
  return x * x + y * y;
}
// 柯里化版本
const currySquares = function(x) {
    return function(y) {
    return x * x + y * y;
    }
}
console.log(squares(1,2));
console.log(currySquares(1)(2));

Function composition combines functions so that the output of one becomes the input of the next:

const compose = (f, g) => x => f(g(x))
const f = x => x * x;
const g = x => x + 2;
const composefg = compose(f, g);
composefg(1) // 9

Multi‑function composition can be implemented with reduceRight :

const compose = (...fns) => (...args) => fns.reduceRight((val, fn) => fn.apply(null, [].concat(val)), args);
const f = x => x * x;
const g = x => x + 2;
const h = x => x - 3;
const composefgh = compose(f, g, h);
composefgh(5); // 16

Object‑Oriented Programming

OOP treats a program as a collection of interacting objects. Core concepts—encapsulation, inheritance, and polymorphism—are demonstrated with ES6 class syntax.

class Zcy {
  constructor(name){
    this.name = name;
  }
  doSomething(){
    let {name} = this;
    console.log(`${name}9点半在开晨会`);
  }
  static soCute(){
    console.log("Zcy 是一个大家庭!");   
  }
}
let member = new Zcy("jingjing", 18);
member.soCute();   // member.soCute is not a function
member.doSomething();  // jingjing9点半在开晨会
Zcy.soCute();  // Zcy 是一个大家庭!

Inheritance allows a subclass to reuse and extend parent behavior while static methods remain bound to the parent class:

class Zcy {
  constructor(name){
    this.name = name;
  }
  doSomething(){
    let {name} = this;
    console.log(`${name}9点半在开晨会`);
  }
  static soCute(){
    console.log("Zcy 是一个大家庭!");   
  }
}
class ZooTeam extends Zcy {
    constructor(name){
        super(name);
    }
    eat(){
      console.log("周五一起聚餐!");
    }
}
let zooTeam = new ZooTeam("jingjing");
zooTeam.doSomething(); // jingjing9点半在开晨会
zooTeam.eat(); // 周五一起聚餐!
zooTeam.soCute(); // zooTeam.soCute is not a function

Polymorphism allows the same operation to behave differently on different objects; in JavaScript this is mainly achieved through method overriding.

Conclusion

No paradigm is inherently superior. In practice, developers often combine paradigms—using imperative or declarative code within functional or object‑oriented structures—to suit specific requirements and achieve maintainable, efficient solutions.

JavaScriptFunctional Programmingprogramming paradigmsobject-orientedCurryingDeclarativecompositionimperative
政采云技术
Written by

政采云技术

ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.