本人看了很多有关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原型
我们先来弄清楚两个概念:
- js分为函数对象和普通对象,每个对象都有__proto__属性,但是只有函数对象才有prototype属性
- Object、Function都是js内置的函数, 类似的还有我们常用到的Array、RegExp、Date、Boolean、Number、String
__proto__和prototype到底是什么
- 属性__proto__是一个对象,它有两个属性,constructor和__proto__;
- 原型对象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
图2
详细说一下,由于原型链的关系,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本质也是一个对象)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。