JavaScript原型与原型链

栏目: JavaScript · 发布时间: 7年前

内容简介:在 JavaScript 中,是一种面向对象的程序设计语言,但是 JS 本身是没有 “类” 的概念,JS 是靠原型和原型链实现对象属性的继承。在理解原型前,需要先知道对象的构造函数是什么,构造函数都有什么特点?以上代码,普通函数

在 JavaScript 中,是一种面向对象的程序设计语言,但是 JS 本身是没有 “类” 的概念,JS 是靠原型和原型链实现对象属性的继承。

在理解原型前,需要先知道对象的构造函数是什么,构造函数都有什么特点?

1. 构造函数

// 构造函数 Person()
function Person(name, gender) {
    this.name = name;
    this.gender = gender;
}

var person = new Person("周杰伦", "男");

// 最后创建出来的对象实例 person
person

{
    name: "周杰伦",
    gender: "男"
}
复制代码

以上代码,普通函数 Person() ,加上 new 关键字后,就构造了一个对象 person

所以构造函数的定义就是普通函数加上 new 关键字,并总会返回一个对象。

2. 函数对象

同时,JS 中的对象分为一般对象和函数对象。那什么是一般对象,什么又是函数对象呢?

JavaScript 的类型分为基本数据类型和引用数据类型,基本数据类型目前有 6 种(null, undefined, string, number, boolean, Symbol)。 其余的数据类型都统称为 object 数据类型,其中,包括 Array, Date, Function等,所以函数可以称为函数对象。

let foo = function(){

}
foo.name = "bar";
foo.age = 24;
console.log(foo instanceof Function)  //true
console.log(foo.age)  // 24
复制代码

以上代码就说明了函数其实是一个对象,也可以具有属性。

二、原型链

JavaScript 中的对象,有一个特殊的 [[prototype]] 属性, 其实就是对于其他对象的引用(委托)。当我们在获取一个对象的 属性 时,如果这个对象上没有这个属性,那么 JS 会沿着对象的 [[prototype]] 链 一层一层地去找,最后如果没找到就返回 undefined ;

这条一层一层的查找属性的方式,就叫做原型链。

var o1 = {
    age: 6
}
复制代码

那么,为什么一个对象要引用,或者说要委托另外一个对象来寻找属性呢?

本文开篇的第一句话,就指出来的,JavaScript 中,和一般的 OOP 语言不同,它没有 '类'的概念,也就没有 '模板' 来创建对象,而是通过字面量或者构造函数的方式直接创建对象。那么也就不存在所谓的类的复制继承。

三、原型

那什么又是原型呢?

既然我们没有类,就用其他的方式实现类的行为吧,看下面这句话↓↓。

1. 每个函数都有一个原型属性 prototype 对象

function Person() {

}

Person.prototype.name = 'JayChou';

// person1 和 person2 都是空对象
var person1 = new Person();
var person2 = new Person();

console.log(person1.name) // JayChou
console.log(person2.name) // JayChou
复制代码

通过构造函数创造的对象,对象在寻找 name 属性时,找到了 构造函数的 prototype 对象上。

这个构造函数的 prototype 对象,就是 原型

用示意图来表示:

JavaScript原型与原型链

查找对象实例属性时,会沿着原型链向上找,在现代浏览器中,标准让每个对象都有一个 __proto__ 属性,指向原型对象。那么,我们可以知道对象实例和函数原型对象之间的关系。

JavaScript原型与原型链

2. 每个原型对象都有一个 constructor 属性指向关联的构造函数

为了验证这一说话,举个例子。

function Person() {}

Person === Person.prototype.constructor; // true
复制代码

那么对象实例是构造函数构造而来,那么对象实例是不是也应该有一个 constructor 呢?

function Person() {}

const person = new Person();
person.constructor === Person // true
复制代码

但事实上,对象实例本身并没有 constructor 属性,对象实例的 constructor 属性来自于引用了原型对象的 constructor 属性

person.constructor === Person.prototype.constructor // true
复制代码
JavaScript原型与原型链

3. 原型链顶层:Object.proto== null

既然 JS 通过原型链查找属性,那么链的顶层是什么呢,答案就是 Object 对象,Object 对象其实也有 __proto__ 属性,比较特殊的是 Object.__proto__ 指向 null , 也就是空。

Object.prototype.__proto__ === null
复制代码
JavaScript原型与原型链

我们回过头来看函数对象:

所有函数对象的proto都指向Function.prototype,它是一个空函数(Empty function)

Number.__proto__ === Function.prototype  // true
Number.constructor == Function //true

Boolean.__proto__ === Function.prototype // true
Boolean.constructor == Function //true

String.__proto__ === Function.prototype  // true
String.constructor == Function //true

// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身
Object.__proto__ === Function.prototype  // true
Object.constructor == Function // true

// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身
Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

Array.__proto__ === Function.prototype   // true
Array.constructor == Function //true

RegExp.__proto__ === Function.prototype  // true
RegExp.constructor == Function //true

Error.__proto__ === Function.prototype   // true
Error.constructor == Function //true

Date.__proto__ === Function.prototype    // true
Date.constructor == Function //true

复制代码

所有的构造器都来自于 Function.prototype,甚至包括根构造器Object及Function自身。所有构造器都继承了·Function.prototype·的属性及方法。如length、call、apply、bind

以图会友,这就是网上经常看到的 JS 原型和原型链关系图:

JavaScript原型与原型链

对于以上看似很复杂的关系图,只需要理解 5 点:

Person.prototype.__proto__ === Object.prototype
Function.prototype.__proto__ === Object.prototype
Object.__proto__

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical Algorithms for Programmers

Practical Algorithms for Programmers

Andrew Binstock、John Rex / Addison-Wesley Professional / 1995-06-29 / USD 39.99

Most algorithm books today are either academic textbooks or rehashes of the same tired set of algorithms. Practical Algorithms for Programmers is the first book to give complete code implementations o......一起来看看 《Practical Algorithms for Programmers》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码