原型和原型链

错误之处,欢迎指正。


1. 原型和原型链

  1. 所有函数都有prototype这个属性,这个属性指向该函数的原型。原型是一个对象格式。
  2. 所有对象都有__proto__这个属性,这个属性指向该对象的构造函数的原型。注意:使用__proto__是不被推荐的一种方式,推荐使用Object上的静态方法Object.getPrototypeOf(obj)来获取该对象的构造函数的原型。
  3. 函数也是对象,函数也具有__proto__这个属性,指向构造函数Function的原型。
  4. Function可以理解为是javascript帮我们写好的,Function.__proto__ === Function.prototype
  5. Object.prototype.__proto__ === null
  6. 当调用一个对象/函数上的属性时,先去自身找,如果自身没有,去__proto__上找(构造该对象的构造函数的原型,xxx.__proto__),如果构造函数的原型上没有,去该构造函数的原型的__proto__上找(构造函数的原型的构造函数的原型xxx.__proto__.__proto__),一直到找到,或者返回null为止。

2. 例题

const F = function () {};  //构造函数F
const obj = new F();  //构造函数F构造的对象obj
Object.prototype.a = 'chris';
Function.prototype.b = '22';
console.log(obj.a);
console.log(obj.b);
console.log(F.a);
console.log(F.b);
  1. 首先看obj.aobj是一个对象,它自身没有a这个属性,那么去它的构造函数原型(obj.__proto__)上寻找,它的构造函数是F,那么该构造函数的原型是F.prototype,然而依然没有,那么继续找F.prototype.__proto__F.prototype是一个对象,它的构造函数是Object,因此,找到了Object.prototype,所以obj.a输出的是chris
  2. 再看obj.b,这里就不再赘述了,从Object.prototype开始说,在这里依然没找到b,那么继续向上找Object.prototype.__proto__,此时返回了null,所以obj.b输出的是undefined
  3. F.aF.bF是一个函数,它自身没有ab这两个属性,那么去它的构造函数原型(F.__proto__)上寻找,它的构造函数是Function,那么该构造函数的原型是Function.prototype,然而依然没有a,但是此时找到了b,所以F.b输出的是22,那么继续找Function.prototype.__proto__Function.prototype是一个对象,它的构造函数是Object,因此,找到了Object.prototype,所以F.a输出的是chris

3. 和原型相关的关键字和属性

  1. instanceof
const obj = {};
function a() {};
console.log(obj instanceof Object);  //true
console.log(obj instanceof Function);  //false
console.log(a instanceof Object);  //true
console.log(a instanceof Function);  //true

简单来说,可以把instanceof当做“是”,例如上述:
obj是个对象”,就正确;“obj是个方法”,很明显这是不正确的。实际上,instanceof是判断obj的原型链上是否有Object的原型。

  1. isPrototypeOf
const obj = {};
function a() {}
console.log(Object.prototype.isPrototypeOf(obj));  //true
console.log(Function.prototype.isPrototypeOf(obj));  //false
console.log(Object.prototype.isPrototypeOf(a));  //true
console.log(Function.prototype.isPrototypeOf(a));  //true

通过isPrototypeOf来判断obj的原型链上是否有object的原型。

  1. hasOwnProperty
Object.prototype.age = '22';
const obj = {
    name: 'chris'
}
console.log(obj.name); //chris
console.log(obj.age);  //22
console.log(obj.hasOwnProperty('name'));  //true
console.log(obj.hasOwnProperty('age'));  //false

判断是自身的属性,还是原型上的属性。

  1. Object.create()
Object.prototype.name = 'chris';
const obj = Object.create(Object.prototype);
console.log(obj.name);  //chris

Object.prototypeobj的隐式原型创建obj

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

推荐阅读更多精彩内容

  • 众所周知js原型及原型链是很多开发者的一个疼点(我也不例外),我也曾多次被问起,也问过不少其他人,如果在自己没有真...
    奔跑的痕迹阅读 358评论 0 6
  • 为什么要理解原型和原型链,因为有利于我们理解和实现 JS对象继承。 __proto__ __proto__是什么W...
    微风玉米阅读 533评论 0 2
  • 构造函数是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创...
    Primers阅读 147评论 0 0
  • 记住一句“内功”: 「对象.__proto __ === 函数.prototype」 一. prototype原...
    Jason_Shu阅读 308评论 0 0
  • 一、原型 上回讲到,生成一个对象我们可以通过new构造函数来实现,如下: 但是,上面这样也有个缺陷,比如每个per...
    Da_xiong阅读 347评论 0 1