javaScript原型与原型链

JavaScript原型与原型链

此处先说明原型与原型链的作用:JavaScript的原型与原型链就是该编程语言为了实现面对对象编程的一种设计,基于原型链,可以让JavaScript对象拥有封装、继承和多态等众多面向对象的特性。

下面我们一步一步来认识它。

JavaScript的面向对象

使用过Vue的小伙伴应该会很熟悉下面这段代码,通过vue-cli创建的Vue项目,在其如口main.js文件中,一般会有如下代码:

image-20210831184437252.png

我们打开Vue的源码,可以看到Vue这个对象的定义,与其它语言有很大的不同,Vue这个对象就是一个function(函数):

image-20210831185237224.png

JavaScript是一门弱类型语言,但它也有其它高级语言(如JavaC#等)所拥有的的特征——面向对象,上面通过newfunction关键字,便是创建了一个Vue对象。

function用来定义一个类,new关键字则用来创建一个类的实例对象。 实例化对象之后, 实例便继承了类的属性和方法。 例如:

function Person(name, age){
  this.name = name;
  this.age = age;
}

Person.prototype.getName = function(){
  return this.name;
};

var person = new Person('james', 18);
console.log(person.name); // putput: james
console.log(person.age); // putput: 18
console.log(person.getName()); // putput: james

JavaScript创建对象的过程

在介绍原型与原型链之前,我们还需要先了解一下JavaScript是如何创建一个对象的

当我们通过new创建一个对象时(如:var person = new Person('james', 18))到底经历了什么呢?

  1. 首先会创建一个空对象Object

    // 在栈内新建了一个obj,这个obj实际上是指的堆中对应的一个地址
    
    let obj = new Object(); 
    
  1. 设置原型链---这里所说原型链,就是设置新建对象obj的隐式原型即_proto_属性指向构造函数Person的显示原型prototype对象,即:

    obj.__proto__ = Person.prototype;
    
  1. 改变构造函数Person的this绑定到新对象obj,并且利用call()或者是apply()来执行构造函数Person,如下:

    let result = Person.call(obj);
    
  1. 将第三步中初始化完成后的对象地址,保存到新对象中,同时要判断构造函数Person的返回值类型,为什么要判断值类型呢?因为如果构造函数中返回this或者是基本数据类型(number数值,string字符串,Boolean布尔,null,undefined)的值时,这个时候则返回新的实例对象,如果构造函数返回的值是引用类型的,则返回的值是引用类型,如下:

    if (typeof (result) === "object") { 
     func = result;
    } else { 
     func = obj; // 默认返回
    }
    

整个过程使用伪代码来模拟其执行的过程:

new Person('james', 18)  = {
  var obj = {};
  obj.__proto__ = Person.prototype;
  var res = Person.call(obj, 'james', 18);
  return typeof res === 'object' ? res : obj;
}

JavaScript的原型与原型链

在通过new关键字创建对象的过程中,在其第二步:obj.__proto__ = Person.prototype,在这一步,就涉及到了原型的概念。

  • prototype: 每一个函数都有一个特殊的属性,叫做原型(prototype)
  • constructor: 相比于普通对象的属性,prototype属性本身会有一个属性constructor,该属性的值为prototype所在的函数
  • __proto__: 每一个对象都有一个__proto__属性,该属性指向对象(实例)所属构造函数(类)的原型prototype

原型与对象的关系图如下:

image-20210901091846381.png

每个实例的的__proto__指向对象的prototype,同时对象prototype__proto__又指向上层对象的prototype。也就是原型链(下面蓝色的这条链)。

image-20210901091945456.png

JavaScript对象的prototype内置属性, 其实就是对于其他对象的引用, 几乎所有的对象在创建时, prototype的属性都会被赋予一个非空的值(除了Object.create(null))。 所有普通的prototype链最终都会指向内置的Object.prototype。在创建一个新对象成功之后, 如果调用一个新对象没有的属性或方法的时候, JavaScript会沿着原型链向上逐层查找对应的属性或方法。 这就类似于类继承

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容