博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【前端芝士树】Javascript的原型与原型链
阅读量:5950 次
发布时间:2019-06-19

本文共 3396 字,大约阅读时间需要 11 分钟。

【前端芝士树】Javascript的原型、原型链以及继承机制

前端的面试中经常会遇到这个问题,自己也是一直似懂非懂,趁这个机会整理一下

0. 为什么会出现原型和原型链的概念

1994年,网景公司(Netscape)发布了Navigator浏览器0.9版,但是刚开始的Js没有继承机制,更别提像同时期兴盛的C++和Java这样拥有面向对象的概念。在实际的开发过程中,工程师们发现没有继承机制很难解决一些问题,必须有一种机制能将所有的对象关联起来。

Brendan Eich鉴于以上情况,但不想把Js设计得过为复杂,于是引入了new关键词constructor构造函数来简化对象的设计,引入了prototype函数对象来包含所有实例对象的构造函数的属性和方法,引入了proto原型链的概念解决继承的问题。

1. Javscript 函数和函数对象

var o1 = {}; var o2 =new Object();var o3 = new f1();function f1(){}; var f2 = function(){};var f3 = new Function('str','console.log(str)');
凡是直接或者间接通过
new Function() 创建的对象都是函数对象,其他的都是普通对象。

在上面的程序中,o1、o2、o3都是普通对象,f1、f2、f3都是函数对象。

2. 构造函数

function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name) } }var person1 = new Person('Zaxlct', 28, 'Software Engineer');var person2 = new Person('Mick', 23, 'Doctor');
person1
person2 都是 构造函数 Person 的实例。
实例的构造函数属性(constructor)指向构造函数。

3. 原型对象

Person.prototype = {   name:  'Zaxlct',   age: 28,   job: 'Software Engineer',   sayName: function() {     alert(this.name);   }}

每个函数对象都有一个 prototype 属性,这个属性就是函数的原型对象

每个对象都有
proto 属性,但只有函数对象才有 prototype 属性

clipboard.png

在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)

Person.prototype.constructor == Person

而在Person这个对象进行实例化的时候,实际上是创建了一个它的实例对象并赋值给它的 prototype,所以得出以下结论:

原型对象(Person.prototype)是 构造函数(Person)的一个实例。

4. _proto_

JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象,也就是prototype。

clipboard.png

Person.prototype.constructor == Person;person1.__proto__ == Person.prototype;person1.constructor == Person;

看下面一段代码

Person.prototype.__proto__ === Object.prototype;

Person.prototype 是一个普通对象,我们无需关注它有哪些属性,只要记住它是一个普通对象。

因为一个 普通对象的构造函数 === Object
所以 Person.prototype.__proto__ === Object.prototype

5. 原型链

原型链的形成是真正是靠__proto__ 而非prototype。
person1.__proto__ === Person.prototype;Person.prototype.__proto__ === Object.prototype;Object.prototype.__proto__ === null;//Object.prototype.__proto__ === null,保证原型链能够正常结束。Person.__proto__ === Function.prototype;Object.__proto__ === Function.prototype;Function.prototype.__proto__ === Object.prototype;

前面三项已经形成了一个原型链,那么后面代码中Person和Object的__proto__都是Function.prototype呢?

所有函数对象的proto都指向Function.prototype,它是一个空函数(Empty function)
Number.__proto__ === Function.prototype  // trueNumber.constructor == Function //trueBoolean.__proto__ === Function.prototype // trueBoolean.constructor == Function //trueString.__proto__ === Function.prototype  // trueString.constructor == Function //trueObject.__proto__ === Function.prototype  // trueObject.constructor == Function // trueFunction.__proto__ === Function.prototype // trueFunction.constructor == Function //trueArray.__proto__ === Function.prototype   // trueArray.constructor == Function //trueRegExp.__proto__ === Function.prototype  // trueRegExp.constructor == Function //trueError.__proto__ === Function.prototype   // trueError.constructor == Function //trueDate.__proto__ === Function.prototype    // trueDate.constructor == Function //true
所有的构造器都来自于 Function.prototype,甚至包括根构造器Object及Function自身。所有构造器都继承了·Function.prototype·的属性及方法。如length、call、apply、bind

所以我们再举一个原型链的例子

let num = new Number();num.__proto__ === Number.prototype;Number.prototype.__proto__ === Function.prototype;Funtion.prototype.__proto__ === Object.prototype;Object.prototype.__proto__ === null;

也可看下图的实现,更直观。

clipboard.png

ok, 所以明白为什么Number、String、Array这样的对象实例能继承到Object的属性以及原型链是怎么一回事了吧。

参考文章

转载地址:http://oasxx.baihongyu.com/

你可能感兴趣的文章
Eclipse安装adt插件后之后看不到andorid manger
查看>>
Kafka服务端脚本详解(1)一topics
查看>>
Zookeeper 集群安装配置,超详细,速度收藏!
查看>>
js中var self=this的解释
查看>>
js--字符串reverse
查看>>
面试题
查看>>
Facebook 接入之获取各个配置参数
查看>>
android ant Compile failed; see the compiler error
查看>>
项目经理笔记一
查看>>
[原]Jenkins(三)---Jenkins初始配置和插件配置
查看>>
Cache Plugin 实现过程
查看>>
HBase Compaction详解
查看>>
TCP服务器端口转发: netsh
查看>>
2016OSC源创会年终盛典-架构与数据专场-张千明
查看>>
nginx实现rtmp,flv,mp4流媒体服务器
查看>>
46.tornado绑定域名或者子域名泛域名的处理
查看>>
Elasticsearch 2.2.0 插件篇:安装
查看>>
文本过滤--sed 1
查看>>
PHP CURL并发,多线程
查看>>
ES 概念及动态索引结构和索引更新机制
查看>>