本人看了很多有关js原型和原型链的文章,但是感觉总是介绍的不完整或者不够清晰,所以特地根据自己所掌握的知识将这些内容梳理一下

1、首先我先来介绍一下什么是对象及在不同语言中是怎么定义的

对象:
比如说在典型的面向对象编程语言(比如 C++ 和 Java),都有“类”(class)这个概念。所谓“类”就是对象的模板,对象就是“类”的实例。但是,JavaScript 语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)
(注:理解这个很重要)


2、介绍下js构造函数

JavaScript 语言使用构造函数(constructor)作为对象的模板。所谓”构造函数”,就是专门用来生成实例对象的函数。它就是对象的模板,描述实例对象的基本结构。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。

构造函数就是一个普通的函数,但是有自己的特征和用法。
例如:

//以下代码均可以在浏览器中正常运行
let Human = function () {
   this.name = "名字";
   this.age = 21;
};
或者这样写
#function Human(name,age){ //可以通过传入参数来初始化值
#  this.name = name;
#  this.age = age;
# }

//我们实例化该函数
let human = new Human();
//打印出实例对象(human)
console.log(human); // {name: "名字", age: 21}
从打印出来的结果来看human就是一个对象

注意:为了与普通函数区别,构造函数名字的第一个字母通常大写

构造函数有两个特点

  • 函数体内部使用了this关键字,this指向所要生成的对象实例(如例子中human)。
  • 生成对象的时候,必须使用new命令。

解释一下this.name在构造函数中是什么意思,this.name表示实例对象(human)中有一个属性name。

《--额外说一下--》
// 我们来看下ECMAScript官网是怎么描述构造函数的

constructor

function object that creates and initializes objects
// 创建和初始化对象的函数对象(描述了构造函数作用)
NOTE

The value of a constructor's "prototype" property is a prototype object that is used to implement inheritance and shared properties.

// 构造函数的“ prototype”属性的值是用于实现继承和共享属性的原型对象。(表明了构造函数中的属性prototype其实是一个对象)

3、介绍下什么是js原型

我们先来弄清楚两个概念:

  1. js分为函数对象普通对象,每个对象都有__proto__属性,但是只有函数对象才有prototype属性
  2. Object、Function都是js内置的函数, 类似的还有我们常用到的Array、RegExp、Date、Boolean、Number、String

__proto__和prototype到底是什么

  1. 属性__proto__是一个对象,它有两个属性,constructor和__proto__;
  2. 原型对象prototype有一个默认的constructor属性,用于记录实例是由哪个构造函数创建;

看如下代码

 function Person(name, age){
    this.name = name;
    this.age = age;
 }
 
 Person.prototype.conmonPropert = '内容值';
 
 //实例化
 let person1 = new Person("张三",21);
 let person2 = new Person("李四",22);
 // 打印一下person1,person2
 console.log(person1);  //看图1
 console.log(person2);  //看图2

图1
1CYKR}_@TE7QGLTJB(M})~C.png
图2
OR78YI1(2{OO93FAX{G_ONW.png

详细说一下,由于原型链的关系,person1和person2中都能访问到conmonPropert这个属性。你们试想一下,Person这个构造函数如果表示人类的话,那是不是它会有更多的属性,比如头发、皮肤、身高等等属性,这些属性都是每个人都有的共通的属性,当共通的属性或者方法越多,原型及原型链的意义就体现出来了。

再说一下原型链这个东西,这个就比较简单了,每个对象中都会隐式的引用__proto__这个对象,每个__proto__对象中都有constructor和__proto__这两个属性。层层嵌套__proto__,直到__proto__属性为null。

就类似这样的关系,正是这样的关系就形成了原型链
__proto__
  __proto__
    __proto__

4、总结及答疑

1、原型有什么用
原型对象的作用,是用来存放共有的那部份属性、方法,可以大大减少内存消耗。

2、原型链是什么
在js中由于每个对象中都隐式的引用了__proto__这个对象,而每个—__proto__对象中又包含了__proto__这个对象,层层嵌套这种关系,形成了原型链,直到__proto__为null。

//梳理下相关知识

js之父在设计js原型、原型链的时候遵从以下两个准则
1. Person.prototype.constructor == Person // **准则1:原型对象(即Person.prototype)的constructor指向构造函数本身**

//取person1作为例子
2. person1.__proto__ == Person.prototype // **准则2:实例对象(即person1)的__proto__和原型对象指向同一个地方**

//注解(prototype本质也是一个对象)

子木兰
15 声望1 粉丝

目前小哥哥我进入前端行业也是有三年了,平常在工作中碰到过一些问题,但是一直没时间去系统化总结,所以利用空闲时间,写一下自己的学习心得,欢迎大家提出意见