一篇文章带你读懂原型与原型链

19 阅读3分钟

既然讲到原型与原型链我们先来比较es5与es6的对象创建区别

ES5中创建对象的方法

  1. 对象字面量: 使用花括号{}包围一组属性和方法来创建对象。
var obj = {
    name: 'Alice',
    age: 30,
    greet: function() {
        console.log('Hello, my name is ' + this.name);
    }
};

  1. 构造函数: 定义一个构造函数,并使用new关键字创建对象实例。
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        console.log('Hello, my name is ' + this.name);
    };
}
var person = new Person('Bob', 25);

es6一般创建对象的方法

1 .类 (Class) :ES6引入了类,它是创建对象的一种更现代和更简洁的方式。在底层,类仍然是基于原型和构造函数的,但它提供了一种更直观和强大的语法。

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    greet() {
        console.log('Hello, my name is ' + this.name);
    }
}

let john = new Person('John', 30);

今天我们重点聊聊原型,我们来看到这段代码

function Person() {

}
var person = new Person();
person.name = 'Kevin';
console.log(person.name) // Kevin

这段例子构造函数就是Person,person是实例

我们来引入原型的概念 几乎每一个JavaScript函数(箭头函数除外)都有一个指向它的原型 (Prototype) 对象的内部链接(null除外)。这个原型对象本质上是一个普通的JavaScript对象,但它具有一些特殊的用途。原型对象主要用于实现基于原型的继承和属性的共享。函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型,也就是这个例子中的 person1 和 person2 的原型

image.png

每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__ ,这个属性会指向该对象的原型

image.png

实例对象和构造函数都可以指向实例原型,那么实例原型能指向构造函数或实例呢? 我们来引入constructor

constructor,每个原型都有一个 constructor 属性指向关联的构造函数

image.png

image.png

image.png

大家可以尝试这段代码

function Person() {

}
console.log(Person === Person.prototype.constructor); // true

综上我们得出这段代码

function Person() {

}

var person = new Person();

console.log(person.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true
// 顺便学习一个ES5的方法,可以获得对象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

那么实例有什么用呢?我们来看看这段例子


function Person() {

}

Person.prototype.name = 'Kevin';

var person = new Person();

person.name = 'Daisy';
console.log(person.name) // Daisy

delete person.name;
console.log(person.name) // Kevin

我们可以看到person实例在有name属性值时输出该属性值,若找不到该属性值则会沿着 原型链一直找,直到找到最近的原型为止,但是-----如果没有找到呢?来,我们来引出原型的原型

var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin

image.png

我们来引入这段代码

console.log(Object.prototype.__proto__ === null) // true

Object.prototype.proto === null Object的原型为null代表什么,为空,所以实例沿着原型链找不到对应的属性时会返回undefine

image.png

image.png 所以实例在查找属性时会沿着一条链寻找是否存在相应属性,这条链状结构我们就叫原型链(蓝色的)

image.png 同学们看完有没有更加理解原型这个概念