Skip to content
프로토타입기술 정리

JavaScript prototypes: instance-level vs prototype-level functions

1 min readTech notesMoved from my Tistory blogRead the Korean original

A prototype is an original form or a typical example, a basis or a standard.

Every object has a hidden internal [[Prototype]].

Put simply, objects and arrays are both linked through the prototype chain, so Array inherits Object's methods. That is why an array can use array methods like concat(), filter(), and map() as well as Object's toString(), valueOf(), and watch() methods.

Below is what I practiced with prototypes in VSC.

js
const dog = { name: "멍멍이", age: 3, owner: { name: "jun" } };

console.log(Object.keys(dog)); // returns the object's keys as an array
console.log(Object.values(dog)); // returns only the object's values as an array
console.log(Object.entries(dog)); // returns each key and value paired in an array

console.log("name" in dog); // returns a boolean for whether the dog object has a 'name' key
console.log(dog.hasOwnProperty("name")); // returns a boolean for whether the dog object has a 'name' key

Object.freeze: can't add, can't delete, can't write, can't redefine properties

Object.freeze(dog); // freeze for object immutability !! applies only to 1Depth

dog.name = "댕댕이";
console.log(dog);
dog.age = 10;
console.log(dog);
delete dog.name;
console.log(dog); // deleting doesn't work either

But what if you change a value at 2 Depth!?
dog.owner.name = "hun";
console.log(dog); // the owner's name does change to 'hun'

const cat = {};
Object.assign(cat, dog); // same as const cat = {...dog} // copies the dog object into the cat object
console.log(cat);
Object.seal(cat); // values in the object can be changed, but adding, deleting, or redefining properties doesn't work
cat.plus = "추가"; // adding a value doesn't work
delete cat.name; // deleting doesn't work
cat.name = "고양이"; // changing a value works
console.log(cat);

console.log(Object.isFrozen(dog)); // checks whether the object is frozen
console.log(Object.isSealed(cat)); // checks whether the object is sealed

Preventing extension: preventExtensions
const tiger = { sound: "어흥" };
Object.preventExtensions(tiger); // prevents extension with preventExtensions
console.log(Object.isExtensible(tiger)); // checks whether the object can be extended
tiger.name = "호랭이";
console.log(tiger); // only adding properties to the object is blocked

const dog1 = { name: "뽀삐", owner: "성준" };
const dog2 = { name: "도기", owner: "성훈" };

function Dog(name, owner) {
  // constructor function
  this.name = name;
  this.owner = owner;
  // instance-level function: it is included in every object created by the constructor, which wastes memory
  this.printName = () => {
    console.log(this.name);
  };
}

// prototype-level function: saves memory
Dog.prototype.printName = () => {
  console.log(this.name);
};

const dog1 = new Dog("뽀삐", "성준");
const dog2 = new Dog("도기", "성훈");

console.log(dog1, dog2); // objects created with the constructor function
dog1.printName(); // the method can be used through the prototype
dog2.printName();

The difference between instance-level and prototype-level functions: if you use a prototype-level function,
every object made with the constructor function can use the prototype method

Overriding
If you redefine a function with the same name at the instance level (child), that is, override it,
the prototype-level (parent) function property gets shadowed

dog1.printName = () => {
  console.log("안녕하세요");
};

dog1.printName(); // prints "안녕하세요" (hello)

Object-oriented programming => benefit: code reuse through inheritance

function Dog(name, owner) {
  // constructor function
  this.name = name;
  this.owner = owner;
  // instance-level function: it is included in every object created by the constructor, which wastes memory
}

Dog.prototype.printName = function () {
  console.log(this.name);
};

function Cat(name, owner, age) {
  Dog.call(this, name, owner); // similar to super
  this.age = age;
}

Cat.prototype = Object.create(Dog.prototype); // it normally inherits Object's prototype, but this changes it to inherit Dog's prototype

Cat.prototype.play = () => {
  console.log("고양이와 놀기!");
};

const cat = new Cat("고양이", "엄성준", 25);
cat.play();
cat.printName(); // cat can use printName, Dog's prototype function, because through Object's create()
// it inherited Dog's prototype

console.log(cat instanceof Cat); // instanceof tells you which constructor function an object inherits from
console.log(cat instanceof Dog); // cat was created with the Cat constructor, and Cat inherits from Dog, so this prints true

const sleep = {
  sleep: () => {
    console.log("쿨쿨쿨");
  },
};

const play = {
  play: () => {
    console.log("우리같이 놀자");
  },
};

function Human(name) {
  this.name = name;
}

Object.assign(Human.prototype, play, sleep); // because Human's prototype was made to inherit the play and sleep objects

const man = new Human("엄성준");

console.log(man);
man.sleep();
man.play();

So, because Array inherits Object's prototype, it can also use object methods.

Object has the Object.freeze() method, which freezes elements at 1 Depth (shallow copy), Object.seal(), which seals the object so you can't add or delete values but can still change them, and lastly Object.preventExtensions(), which prevents extension.

What I learned from this practice is the difference between an instance-level function created inside a constructor function and a function declared on the constructor's prototype. Here is how they differ: an instance-level function declared inside the constructor gets assigned to every object the constructor creates, and that can waste a lot of memory.

But if you declare a prototype-level function through prototype, you save memory, and every object created by the constructor function can still use the prototype method.

In one line: the biggest difference between a function inside the constructor and a function created through prototype is memory!

  • #JavaScript prototype
  • #Array inherits Object's prototype
  • #benefits of prototype
  • #saving memory
  • #instance level
  • #prototype level

More in Tech notes