js中的原型与原型链

Rosalba ·
更新时间:2024-09-20
· 746 次阅读

面向对象、面向过程和构造函数

面向对象:把数据和对数据的操作方法放在一起,构成一个相互依存的整体,对象和对象之间可以通信,程序流程由用户在使用中确定。
面向过程:自顶向下执行,程序结构按照功能划分成各个基本的模块,程序的流程在写程序时已经确定。
在js中创建对象有两种办法,对象字面量和使用new表达式,在使用new表达式创建对象时就使用到了构造函数。

一个函数作为构造函数和普通函数返回值是不同的。

当return的内容是引用类型时 function Test(){ this.a = 10; return function(){ return 1; } // return 1; } var b = Test(); console.log(b); console.log(typeof(b)); var c = new Test(); console.log(c); console.log(typeof(c));

运行结果如下
在这里插入图片描述
c作为Test构造函数的实例,this.a丢失,被返回值所取代。

当return的内容是值或者没有return时 function Test(){ this.a = 10; // return function(){ // return 1; // } return 1; } var b = Test(); console.log(b); console.log(typeof(b)); var c = new Test(); console.log(c); console.log(typeof(c));

运行结果如下
在这里插入图片描述
这时构造函数成功的构造了c实例。

new关键字做了什么 在构造函数内创建了一个临时的对象 将构造函数内临时对象的__proto__属性和构造函数的原型进行绑定 将临时对象的作用域赋给真正的对象即改变this指针的指向,并将创建好的对象返回 将所有构造函数的原型统一命名为prototype 原型和原型链

我个人觉得最绕的地方,首先名词多,然后互相之间的关系歪七扭八的。接下来我用我能理解的方法解释下这个问题。
这个问题的产生是为了实现原型上属性和方法的继承,提高代码的复用率。构造函数就相当于模具,但是关于这个模具具体的一些属性,比如大小,材质之类的并没有直接写在模具里,而是把这些属性和方法放在了原型(prototype)里,在构造函数内部通过__proto__属性将两者绑定了。在js万物皆对象的思想下,__proto__属性是每个对象都有的,包括原型。
ps:因为绝大部分浏览器都支持__proto__属性,所以它才被加入了 ES6 里(ES5 部分浏览器也支持,但还不是标准)。

然后在有了模具的前提下,就可以来创造实例了,但是实例不光可以继承属性和方法,还可以有自己的属性和方法。就像父子的关系一样,虽然相似但也有不同。而原型中也有一个属性指向创造出来的实例,就是构造器(constructor)属性,构造器(constructor,包括: Object;Function;Array;Date;String等函数)才有prototype属性,对象(除Object外)都拥有__proto__。

所以在通过构造函数创造实例的过程中,构造函数只是一个桥梁,将实例通过原型创造出来了而已,在实例被创造出来的时候,构造函数中的this指针就已经指向被创造的实例,实例的__proto__就指向了实例的原型,而构造函数就退出历史舞台。而原型链指的是,在找寻某个实例的方法和属性的过程中,先在自身查找,然后通过实例的__proto__找到实例的原型,实例的原型再通过实例的原型的__proto__找到了Object的原型,Object的原型再通过Object的原型的__proto__找到Object的原型的__proto__的原型为null,就到顶了。所以说原型链是通过__proto__而不是原型,而且这个连接存在在实例和原型之间,和构造函数没有什么关系。

以下是引用

所有函数对象proto都指向 Function.prototype,它是一个空函数(Empty function)。

1、Object.proto === Function.prototype // true
Object 是函数对象,是通过new Function()创建的,所以Object.__proto__指向Function.prototype。
2、Function.proto === Function.prototype // true
Function 也是对象函数,也是通过new Function()创建,所以Function.__proto__指向Function.prototype
3、Function.prototype.proto === Object.prototype //true
Function.prototype是个函数对象,理论上他的__proto__应该指向 Function.prototype,就是他自己,自己指向自己,没有意义。
JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向Object.prototype。Object.prototype.proto === null,保证原型链能够正常结束。

在这里插入图片描述

在这里插入图片描述

参考文章


作者:Reilyyy



js中 原型链 js

需要 登录 后方可回复, 如果你还没有账号请 注册新账号