您的位置:首页 > Web前端 > JavaScript

一篇文章图文并茂地带你轻松学完 JavaScript 原型和原型链

2021-02-03 23:29 841 查看

JavaScript 原型和原型链

在阅读本文章之前,已经默认你了解了基础的

JavaScript
语法知识,基础的
ES6
语法知识 。 本篇文章旨在为
JavaScript继承
打下基础

原型

  1. JavaScript
    里任何一个函数都有一个
    prototype
    属性,这个属性称之为原型
function Person() {
this.name = "name";
}
console.log(Person.prototype)

Person.prototype
实际上是一个包含
constructor
属性的对象

constructor
实际上就是构造函数本身

// Person.prototype
{
constructor: Person
}
  1. Person.prototype
    指向的对象很特殊(原型链学完就明白为什么特殊了),可以被实例所共享,可以作为实例的属性直接调用
const obj1 = new Person();
const obj2 = new Person();
console.log(obj1.constructor === obj2.constructor) 	// true
console.log(obj1.constructor === Person)			// true

这意味着,我们可以在

Person.prototype
上加一些共享属性或者方法,然后直接在实例中共享

Person.prototype.eat = function() {
console.log("eat");
}

// 现在
obj1.eat(); // "eat";
obj2.eat(); // "eat";

上面,我们简要的说明了原型,以及原型的作用,下面我们探索原型链

原型链

我们先看一个小例子

function Person() {
this.name = "name";
}

const p = new Person();
p.toString(); 			// [object Object]

我们并没有在

Person.prototype
上定义
toString
这个方法,按理来说当我们调用的时候应该报错 ,然而浏览器却 "不厚道" 的输出了
[object Object]

要解释这个原因,还有 "很长的路" 要走。

  1. 首先任何实例化出来的对象都拥有
    __proto__
    属性,这个属性指向构造函数的
    prototype
console.log(p.__proto__ === Person.prototype) // true

之前我们写过这样的代码

Person.prototype.eat = function() {
console.log("eat");
}

obj1.eat(); // "eat";
obj2.eat(); // "eat";

我们惊讶的发现,

obj1
上也可以拥有
eat
方法了。

  1. 如果一个对象上没有这个属性,他就会去他的
    __proto__
    属性对应的对象上去找,如果还没有就继续这个对象的
    __proto__
    上去找

那么

Person.prototype
是否有
__proto__

console.log(Person.prototype.__proto__);

在这里输出的结果中有

constuctor: Object

之前提到

constuctor
其实就是构造函数本身,因此

console.log(Person.prototype.__proto__ === Object.prototype); // true

我们在

Object.prototype
中发现了这个方法,并进行调用

console.log(Object.prototype.hasOwnProperty("toString")) // true
Object.prototype.toString.call(p); // [object Object]

至此原型链基本是说完了,有兴趣的可以探究一下

  1. Object.prototype
    是否有
    __proto__
    ?
  2. 构造函数是否也是被实例化出来的?
  3. 数组的原型链是什么样的

对于第三题,有兴趣的可以自己画一下图

console.log(Array.prototype.__proto__ === Object.prototype) // true
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: