理解JavaScript原型和原型链

  • A+
所属分类:Web前端
摘要

理解JavaScript原型和原型链 ( 资料整理,个人学习) (原文链接https://www.cnblogs.com/piaobodewu/p/13795077.html)

理解JavaScript原型和原型链 (资料整理,个人学习)

 

(原文链接https://www.cnblogs.com/piaobodewu/p/13795077.html)

精典图

理解JavaScript原型和原型链

 

 

 注意:

(prototype-原型, _proto_-继承)

1:只有Functions集合中的function有prototype属性。

2:function的prototype指向Prototypes集合中的实例。

3:Prototypes集合中的实例constructior属性指向Functions集合中的function。

4:(new xx())对象中有_proto_属性。

5:(new xx())对象_proto_指向Prototypes集合中的实例

6:Functions集合中的function在new 的同时都继承(_proto_)同一个Prototypes集合中的function的实例。

 

一切起源于null

理解JavaScript原型和原型链

 

 

 机器1号可不得了,它是JS世界的第一个对象,它是真正的万物始祖。它拥有的性质,是所有的对象都有的。
__proto__是什么呢?是“生”的意思,或者换成专业点的叫法“继承”.

 

有中生有

一生二,二生三,三生万物

理解JavaScript原型和原型链

 

 

 通过object创造对象,Object制造对象时候,需要有一个模版,现在只有机器1号,它就取了机器1号当模版。图中的prototype就代表模板对象。

通过new命令。按下“new”按钮,新的对象就造出来了。var obj = new Object();

理解JavaScript原型和原型链

 

 

 Object通过(prototype)模板创造new对象,对象通过(_proto_)继承模板,

 

 有生万物

(注:__proto__

来代替)

理解JavaScript原型和原型链

 Object也指向了机器2号,这是因为机器2号是负责造对象的,当然也负责造Object对象

Object有自己的模板:机器1号。而String、Number、Boolean、Array它们有模板吗?

其实机器2号在创建它们的时候并不是直接创建它们的,而是先创建了对应对象的机器作为模板,然后再由各自的机器来创建它们。

机器2号总体负责制造所有的对象,包含Object、String、Number、Boolean、Array,甚至还有之后的Function。当然它只是负责制造,并不一定会亲手去制造对象,可以通过制造对应的机器来帮助它制造对象

理解JavaScript原型和原型链

 

  • 机器1号制造了机器2号,机器2号总体负责各种对象的制造
  • 但是机器2号并不是直接造各种对象,而是通过先建造对应的机器(模板),再由对应的机器来制造对象(继承)。如:对于String,机器2号先制造了机器String号,然后由机器String号来制造String,机器2号只负责总体控制
  • 虽然机器2号制造了各种各样的机器,但是因为机器2号是由机器1号制造的,所以这些被制造的机器所属权还是归于机器1号的,毕竟机器1号是始祖级的。
  • 对象和对应的机器,通过prototype来连接。如:对于String,机器2号String通过prototype连接
  • 每个机器都有且只有一个的对象,每个对象也都有且只有一个机器作为模板

万物缺活力-Function的制造

  • 它是由机器2号亲手制造的,所以它们之间有prototype相连
  • 而机器2号又是制造所有对象的负责者,所以它们之间有__proto__相连
  • Function.__proto__ === Function.prototype

理解JavaScript原型和原型链

 

  • 机器1号 = Object.prototype(机器1号是Object的模板)
  • 机器2号 = Function.prototype(机器2号是Function的模板)
  • 机器String号 = String.prototype(机器String是String的模板)
  • Function对象作为一个函数,就会有prototype属性,该属性将对应”function () {}”对象。
    Function对象作为一个对象,就有__proto__属性,该属性对应”Function.prototype”,
  • 也就是说,”Function._proto_ === Function.prototype”。

世界动起来

刚造出来的Function机器很难用,用法就像下面这个

let Foo = new Function("name", "console.log(name)");

Foo('dellyoung'); // 控制台打印出:dellyoung

语法糖

function Foo(name) { console.log(name); }

Foo('dellyoung'); // 控制台打印出:dellyoung

以造Foo()为例,于是JavaScript的世界的变成了下面的样子:

理解JavaScript原型和原型链

 

 

  • 机器Foo()号 = Foo.prototype
  • __proto_

Function这个对象比较特殊,它new出来后,就是一个全新的对象了,function Foo()(注意:它等价于 let Foo = new Function())和ObjectStringNumber等这些对象一样,都是对象。

既然都是对象,当然function Foo()也是由机器2号来控制制造的,但是机器2号很忙,它没有精力直接制造function Foo(),机器2号是通过制造出一个制造function Foo()的机器来制造function Foo()

咱们称制造function Foo()的机器机器Foo()号

当然既然是机器,所以机器Foo()也是机器1号控制的

回到现实

 理解JavaScript原型和原型链

 

 可以被用来new的对象或函数,我们都可以称之为构造函数,每个构造函数都和它的机器(也就是XXX.prototype)通过constructor相连,我们来画出构造函数和它们的constructor

 理解JavaScript原型和原型链

 

 

正式的语言总结一下就是:?

 

  • 子类的__proto__属性,表示构造函数的继承,总是指向父类。
  • 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
  • 原型也是一个对象,通过原型可以实现对象的属性继承
  • 对于所有的对象,都有__proto__属性,这个属性对应该对象的原型.

 

var p = new Person('张三',20);

1. var p={}; 初始化一个对象p。
2. p._proto_=Person.prototype;,将对象p的 __proto__ 属性设置为 Person.prototype
3. Person.call(p,”张三”,20);调用构造函数Person来初始化p。关于call/apply使用

总结:

1. 所有的对象都有__proto__属性,该属性对应该对象的原型.
2. 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对象的_proto_属性.
3. 所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数.
4. 函数对象和原型对象通过prototype和constructor属性进行相互关联.

 

 


 

(原文地址:https://zhuanlan.zhihu.com/p/23026595)

<什么是原型>

JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object ,Function 是JS自带的函数对象。

每个对象都有原型(null和undefined除外),你可以把它理解为对象的默认属性和方法。

理解JavaScript原型和原型链

 

 

 Object:Object是一个函数对象,Object的原型就是一个Object对象,它里面存在着一些对象的方法和属性,例如最常见的toString方法。

新建对象:用new Object或者{}建的对象是普通对象,它没有prototype属性,只有__proto__属性,它指向Object.prototype。

Array:Array也是一个函数对象,它的原型就是Array.prototype,它里面存在着一些数组的方法和属性,例如常见的push,pop等方法。

Function:Function也是一个函数对象,但它有点特殊,它的原型就是一个function空函数。

自定义函数:它的原型就是你给它指定的那个东西。如果你不指定,那它的原型就是一个Object.prototype。

 

<什么是原型链>

在JavaScript 中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null 为止(也就是不再有原型指向),组成这条链的最后一环。这种一级一级的链结构就称为原型链(prototype chain)

JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

理解JavaScript原型和原型链

 

 

 当你用new Object或者直接定义一个对象时,它的原型链就是:

o ==Object.prototype ==null;o._proto_==Object.prototype
访问o上没有的属性或方法时,JS会往Object.prototype上寻找该属性和方法。
如果有则直接返回,如果没有,方法则报错,这个方法未定义,属性则返回undefined

o.__proto_指向原型对象,原型对象被赋值给创建的对象_proto_属性中.o对象没有prototype
理解JavaScript原型和原型链
 

理解JavaScript原型和原型链

理解JavaScript原型和原型链

 

 Person所有对象都有公共属性-Person.prototype = {age:24};

Person是构造函数,tsrot函数对象(构造对象)。用构造函数(构造函数我们一般首字母大写)建立一个对象时,它的原型链就是 

 tsrot ==Person.prototype ==Object.prototype ==null

 tsrot.__proto__=Person.prototype;

Person.prototype.__proto__=Object.prototype;

 

 理解JavaScript原型和原型链

Parent和child都是构造函数,

 

理解JavaScript原型和原型链

 

 理解JavaScript原型和原型链

fun是一个函数对象,它是由Function构造函数new的

<prototype与__proto__>

在Javascript中,每个函数都有一个原型属性prototype指向自身的原型,而由这个函数创建的对象也有一个__proto__属性指向这个原型,

而函数的原型是一个对象(函数点prototype也是一个普通对象,Function.prototype除外,它是函数对象,但它很特殊,他没有prototype属性),

所以这个对象也会有一个__proto__指向自己的原型,这样逐层深入直到Object对象的原型,这样就形成了原型链。

普通对象没有prototype,但有__proto__属性。

理解JavaScript原型和原型链

 

理解JavaScript原型和原型链

 

 

 理解JavaScript原型和原型链

 


 

(原文地址https://www.cnblogs.com/tg666/p/12059205.html)

Person 就是一个构造函数,使用 new 创建了一个实例对象 person

 理解JavaScript原型和原型链

 

 

prototype

  每个函数都有一个 prototype 属性

理解JavaScript原型和原型链

 

 理解JavaScript原型和原型链

 

 

proto

  每一个 javaScript 对象(null除外)都具有的一个属性叫 proto ,这个属性会指向该对象的原型

理解JavaScript原型和原型链

 

 理解JavaScript原型和原型链

 

 

constructor

  每一个原型都有一个 constructor 属性指向关联的构造函数,实例原型指向构造函数

理解JavaScript原型和原型链

 

 理解JavaScript原型和原型链

 

 理解JavaScript原型和原型链

 

 实例与原型

 

 理解JavaScript原型和原型链

 

 原型与原型

理解JavaScript原型和原型链

 

Person.prototype也是一个对象,具有_proto_属性指向Object的原型

 理解JavaScript原型和原型链

 

 原型链

理解JavaScript原型和原型链