JavaScript原型与原型链

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

内容简介:在 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__

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

查看所有标签

猜你喜欢:

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

Web性能优化

Web性能优化

Patrick Killelea 谢 / 谢文亮 / 清华大学出版社 / 2003-11-01 / 49.00元

本书讲述如何将Web性能调至最佳状态。书中不仅谈到了Web服务器软件的优化,而且还涉及到如何流水化处理Web内容,如何从浏览器端着手优化性能,如何调校客户端和服务器的硬件,以及如何最大限度地使用网络本身的特性。 书中的内容涉及到影响性能好坏的本质,并为得到立竿见影的效果提供了具体建议。本书向您娓娓道出评价计算性能高低的准则,并在后半部分讲述从客户端、网络直到服务器这一链条中每个环节的薄弱之一起来看看 《Web性能优化》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试