# ProtoType

## Introduction

* Every object in JavaScript has a built-in property, which is called its **prototype**. The prototype is itself an object, so the prototype will have its own prototype, making what's called a **prototype chain**. The chain ends when we reach a prototype that has `null` for its own prototype.
* When you try to access a property of an object: if the property can't be found in the object itself, the prototype is searched for the property. If the property still can't be found, then the prototype's prototype is searched, and so on until either the property is found, or the end of the chain is reached, in which case `undefined` is returned.

### Example

```javascript
const myDate = new Date();
let object = myDate;

do {
  object = Object.getPrototypeOf(object);
  console.log(object);
} while (object);

// Date.prototype
// Object { }
// null
```

<figure><img src="/files/dqLC8rp6uePXPKszYQNe" alt=""><figcaption></figcaption></figure>

## Setting ProtoType of Object

### Method 1 (Object Assign)

```javascript
// case 1
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.log = function () {
    console.log(this.name + ', age:' + this.age);
  }
}

var nick = new Person('nick', 18);
var peter = new Person('peter', 20);

console.log(nick.log === peter.log) // false

// case 2
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const PersonPrototype = {
  log(){
      console.log(this.name + ', age:' + this.age);
  }
}

Object.assign(Person.protoType, PersonPrototype);
// or Person.prototype.log = personPrototype.log;

var nick = new Person('nick', 18);
var peter = new Person('peter', 20);

console.log(nick.log === peter.log) // true
// since the method is shared without creating new reference same as case 1
```

### Method 2 (By property)

```javascript
// case 1
const parent = {
  value: 2,
  method() {
    return this.value + 1;
  },
};

console.log(parent.method()); // 3
// When calling parent.method in this case, 'this' refers to parent

// child is an object that inherits from parent
const child = {
  __proto__: parent,
};
console.log(child.method()); // 3
// When child.method is called, 'this' refers to child.
// So when child inherits the method of parent,
// The property 'value' is sought on child. However, since child
// doesn't have an own property called 'value', the property is
// found on the [[Prototype]], which is parent.value.

child.value = 4; // assign the value 4 to the property 'value' on child.
// This shadows the 'value' property on parent.
// The child object now looks like:
// { value: 4, __proto__: { value: 2, method: [Function] } }
console.log(child.method()); // 5
// Since child now has the 'value' property, 'this.value' means
// child.value instead


// case 2
const obj = {};
// DON'T USE THIS: for example only.
obj.__proto__ = { barProp: "bar val" };
obj.__proto__.__proto__ = { fooProp: "foo val" };
console.log(obj.fooProp);
console.log(obj.barProp);
```

### Method 3 (By setPrototypeOf)

```javascript
const obj = { a: 1 };
const anotherObj = { b: 2 };
Object.setPrototypeOf(obj, anotherObj);
console.log(obj.b) // 2
// obj ---> anotherObj ---> Object.prototype ---> null
```

### Method 4 (By Class)

```javascript
// case 1
function Base() {}
function Derived() {}
// Set the `[[Prototype]]` of `Derived.prototype`
// to `Base.prototype`
Object.setPrototypeOf(Derived.prototype, Base.prototype);

const obj = new Derived();

// equal
class Base {}
class Derived extends Base {}

const obj = new Derived();
// obj ---> Derived.prototype ---> Base.prototype ---> Object.prototype ---> null


// case 2
// A constructor function
function Box(value) {
  this.value = value;
}

// Properties all boxes created from the Box() constructor
// will have
Box.prototype.getValue = function () {
  return this.value;
};

// equal
class Box {
  constructor(value) {
    this.value = value;
  }

  // Methods are created on Box.prototype
  getValue() {
    return this.value;
  }
}
```

## Decide own property

```javascript
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const PersonPrototype = {
  log(){
      console.log(this.name + ', age:' + this.age);
  }
}

// Person.prototype.log =  PersonPrototype.log;
Object.assign(Person.prototype, PersonPrototype);
var nick = new Person('nick', 18);
nick.log(); // nick, age:18
console.log(nick.hasOwnProperty('log')); // false
console.log(nick.__proto__.hasOwnProperty('log')); // true
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://petercheng7788.gitbook.io/developer-note/programming-language/javascript/prototype.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
