What it does: Built-in JavaScript objects (Array, Object, String, etc.) use prototypes to give you all those methods you use daily.
How Built-in Objects Actually Work:
Where Your Methods Come From:
javascript
let obj = {}; // Same as: new Object()
obj.toString(); // "[object Object]"
// Where did toString come from?
console.log(obj.__proto__ === Object.prototype); // true
console.log(obj.toString === Object.prototype.toString); // trueThe Built-in Prototype Chain:
javascript
let arr = [1, 2, 3]; // Same as: new Array(1, 2, 3)
// Chain: arr → Array.prototype → Object.prototype → null
console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__.__proto__.__proto__); // null
arr.push(4); // Method from Array.prototype
arr.toString(); // "1,2,3" (Array.prototype.toString, not Object's)Functions Are Objects Too:
javascript
function myFunc() {}
console.log(myFunc.__proto__ === Function.prototype); // true
console.log(myFunc.__proto__.__proto__ === Object.prototype); // true
myFunc.call(); // Method from Function.prototypeHow Primitives Get Methods:
Temporary Wrapper Objects:
javascript
"hello".toUpperCase(); // How does a string have methods?
// JavaScript secretly does this:
// 1. Creates: new String("hello")
// 2. Calls: tempStringObj.toUpperCase()
// 3. Returns result and destroys temp object
console.log("hello".__proto__ === String.prototype); // trueThe Memory-Efficient System:
javascript
// All arrays share the SAME Array.prototype object in memory
let arr1 = [1, 2];
let arr2 = [3, 4];
console.log(arr1.__proto__ === arr2.__proto__); // true (same memory address!)The Universal Chain:
Everything Inherits from Object:
javascript
// Array → Object
console.log(Array.prototype.__proto__ === Object.prototype); // true
// String → Object
console.log(String.prototype.__proto__ === Object.prototype); // true
// Function → Object
console.log(Function.prototype.__proto__ === Object.prototype); // true
// Object is the top
console.log(Object.prototype.__proto__); // nullInterview Gotchas:
javascript
// Gotcha 1: Method shadowing - closer prototype wins
let arr = [1, 2, 3];
arr.toString(); // "1,2,3" (Array.prototype.toString)
// NOT "[object Array]" (Object.prototype.toString)
// Gotcha 2: Primitives can't store properties
let str = "hello";
str.newProp = "test";
console.log(str.newProp); // undefined (wrapper object destroyed!)
// Gotcha 3: null and undefined have no prototypes
console.log(null.__proto__); // TypeError!
console.log(undefined.toString); // TypeError!
// Gotcha 4: Modifying native prototypes affects EVERYTHING
String.prototype.shout = function() { return this.toUpperCase(); };
"hello".shout(); // "HELLO"
"world".shout(); // "WORLD" (all strings get it!)Method Borrowing:
Stealing Array Methods:
javascript
let arrayLike = {
0: "a",
1: "b",
length: 2
};
// Borrow Array's join method
arrayLike.join = Array.prototype.join;
console.log(arrayLike.join("-")); // "a-b"
// Or call it directly
let result = Array.prototype.slice.call(arrayLike);
console.log(result); // ["a", "b"]Never Get Tricked - Follow These Rules:
- Memory sharing - All instances share the same prototype object
- Chain lookup - Closer prototype methods win over farther ones
- Primitives get temporary wrappers - can’t store custom properties
- Don’t modify native prototypes - unless polyfilling missing features
- Method borrowing works - if the method only needs indexes/length
Bottom line: JavaScript gives you built-in methods through a shared prototype system where everything ultimately inherits from Object, making the language memory-efficient but powerful.
