JavaScript之原型与原型链

万物皆对象

在JavaScript中除值类型之外,其他的都是对象,为了说明这点,我们举几个例子
我们可以使用typeof来做类型判断

typeof a;             // undefined
typeof 1;             // number
typeof 'wclimb';      // string
typeof true;          // boolean

typeof function(){};  // function
typeof [];            // object
typeof null;          // object
typeof {};            // object

除了undefinednumberstringboolean属于值类型之外,其他都是对象。你可能要问了,不是还有一个是function吗?要校验他是不是应该对象可以这样做:

var fn = function(){}
fn instanceof Object // true

由上面的例子所示,函数确实是对象,为什么呢?我们看一下下面的例子

function Person(name){
    this.name = name; 
}
var person = new Person('wclimb');
console.log(person) // Person {name: "wclimb"}

由此我们可以得知,对象都是通过函数创建的,这么说你可能又会说不对,你看下面的就不是函数创建的

var person = {name:'wclimb'}

你咋就这么飘呢?我竟无言以对,没错,这是个意外、意外、意外。但是归根结底他还是通过函数创建的

    var person = new Object()
    person.name = 'wclimb'

so,现在你只要知道对象是通过函数创建的就可以了,来跟着我读:
第一遍 对象都是通过函数创建的
第二遍 对象都是通过函数创建的
第三遍 对象都是通过函数创建的

构造函数(constructor)

function Person(name){
    this.name = name
}
var person1 = new Person('wclimb 1')
var person2 = new Person('wclimb 2')

上面Person就是一个构造函数,我们通过new的方式创建了一个实例对象person
我们来看看person1和person2的constructor(构造函数)是不是指向Person的

person1.constructor === Person // true
person2.constructor === Person // true

原型(prototype)

在JavaScript中,每定义一个函数都会产生一个prototype(原型)属性,这个属性指向函数的原型对象

function Person(){}
Person.prototype.name = 'wclimb'
Person.prototype.age = '24'
Person.prototype.sayAge = function(){
    console.log(this.age)
}
var person = new Person()
person.sayAge(); //  24

那么这个prototype到底是什么呢?跟构造函数有关系吗?

image

上图就可以反映出他们之间的关系

其实函数的prototype指向函数的原型对象,每个对象都会关联另外一个对象,也就是原型,上面的例子改成:

Person.prototype = {
    name: 'wclimb',
    age: 24,
    satAge: function(){
        console.log(this.age)
    }
}

隐式原型(__proto__)

上面我们说到每定义一个函数都会产生一个原型,每个函数它不止有原型,还有一个__proto__(隐式原型)
每个对象都有一个__proto__属性,指向创建该对象函数的prototype,我们可以来试试,还是上面的例子:

function Person(){}
var person = new Person()
person.__proto__ === Person.prototype // true

现在他们的关系图如下

image

由上图我们可以知道:

Person.prototype.constructor = Person
person.__proto__ = Person.prototype
person.constructor = Person

我们可以看到person.__proto__指向构造函数的原型,那么构造函数的原型即Person__proto__指向哪里呢?
我们知道构造函数其实就是由Function来创建的,由此得出:

Person.__proto__ === Function.prototype

那么构造函数的原型即Person.prototype__proto__指向哪里呢?
原型对象其实是通过Object生成的,自然而然的得出:

Person.prototype.__proto__ === Object.prototype

那么Object.prototype__proto__指向哪里呢?答案是null,最终得到下面的图

image

抛开这张图,来看看下面几道题

  1. person.__proto__
  2. Person.__proto__
  3. Person.prototype.__proto__
  4. Object.__proto__
  5. Object.prototype.__proto__

解:

  1. 每个对象都有一个__proto__属性,指向创建该对象函数的prototype,因为Person是person的构造函数
    Person === person.constructortrue,所以:person.__proto__ === Person.prototype
  2. Person构造函数是由Function创建的,所以可以得出Person.__proto__ === Fucntion.prototype
  3. 我们上面说过Person.prototype其实是一个对象,而对象是由Object创建的,所以 Person.prototype.__proto__ === Object.prototype
  4. Object对象都是函数创建的,所以Object.__proto__ === Function.prototype
  5. 虽然Object.prototype是一个对象但是他的__proto__null

实例和原型

当我们要取一个值的时候,会先从实例中取,如果实例中存在,则取实例的值,如果实例不存在,则会顺着原型里找,直到找到

function Person(){}
Person.prototype.name = '我来自原型'

var person = new Person()
person.name = '我来自实例'
console.log(person.name); // 我来自实例
delete person.name
console.log(person.name)); // 我来自原型

首先person实例中有这个属性,返回我来自实例,然后将它删除之后,会从原型中招,也就是person.__proto__,因为Person.prototype === person.__proto__,所以得到我来自原型

总结

原型和原型链基本已经讲解完,不过还有待完善,如有错误,还望指正

GitHub:wclimb

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

推荐阅读更多精彩内容

  • 点击此处访问我的github了解更多详情 在基于类的语言中,对象是类的实例,并且类可以从另一个类继承,如Java;...
    惊鸿三世阅读 514评论 0 4
  • 原型链是一种机制,指的是 JavaScript 每个对象都有一个内置的 __proto__ 属性指向创建它的构造函...
    劼哥stone阅读 4,335评论 15 79
  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,076评论 0 6
  • JS中原型链,说简单也简单。 首先明确: 函数(Function)才有prototype属性,对象(除Object...
    前小白阅读 3,850评论 0 9
  • 几天前,前几天,算是终于把龙族三看完了。 横亘连绵了好几个时空,终于了解到了绘梨衣,这个令人心疼的姑凉的死。三年前...
    奕布小新阅读 1,056评论 0 1