原型(prototype)
在 JavaScript 中,每一个对象都有一个内部属性 [[prototype]],也可以称之为原型。原型是一个对象或 null。当我们访问一个对象的属性或方法时,如果对象本身没有这个属性或方法,那么 JavaScript 引擎会去对象的原型链上查找。也就是说,对象的原型链上的对象都可以为该对象提供属性和方法。
每一个构造函数(除了箭头函数)都有一个原型对象。我们可以通过构造函数的 prototype 属性来访问该原型对象。因此,所有通过该构造函数创建的对象都共享该原型对象。
示例代码:
function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name);
}
const person1 = new Person("Alice");
person1.sayHello(); // "Hello, I'm Alice"
const person2 = new Person("Bob");
person2.sayHello(); // "Hello, I'm Bob"
 
在上面的代码中:
Person是一个构造函数,它有一个原型对象Person.prototype。Person.prototype中定义了一个方法sayHello。- 通过 
new关键字使用Person构造函数创建了两个对象person1和person2。 person1和person2都可以调用sayHello方法,因为它们都从Person.prototype原型对象上继承了该方法。
原型链(prototype chain)
JavaScript 中的原型链是一种对象间的委托关系。当我们访问一个对象的属性或方法时,如果该对象本身没有该属性或方法,那么 JavaScript 引擎会沿着该对象的原型链依次查找,直到找到该属性或方法或找到原型链的顶端 Object.prototype(Object.prototype 是所有对象的根原型对象,它的 [[prototype]] 属性为 null)为止。
示例代码:
function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name);
}
const person = new Person("Alice");
console.log(person.hasOwnProperty("name")); // true
console.log(person.hasOwnProperty("sayHello")); // false
console.log(Person.prototype.hasOwnProperty("sayHello")); // true
console.log(person.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
 
在上面的代码中:
person对象的name属性是它自己的属性,因此person.hasOwnProperty("name")返回true。person对象的sayHello方法不是它自己的属性,而是它的原型对象Person.prototype的属性,因此person.hasOwnProperty("sayHello")返回false。Person.prototype的sayHello方法是它自己的属性,因此Person.prototype.hasOwnProperty("sayHello")返回true。person.__proto__指向Person.prototype,因此person.__proto__ === Person.prototype返回true。Person.prototype.__proto__指向Object.prototype,因此Person.prototype.__proto__ === Object.prototype返回true。Object.prototype.__proto__为null,因为它没有更高层的原型对象,所以Object.prototype.__proto__返回null。










