首页 > 专栏 > 前端 > 文章详情
理解:js中 构造函数 与 原型的对应关系 发布于:2023-02-07 11:19:19   来源:进击的前端面试   查看:93  讨论:0
首先,JS 是真正的“面向对象”的语言,而其他诸如  C++ 、Java等,严格意义上来说,都是面向“类”的语言,仔细想想,还真是那么回事。RPT易塔云建站-模板下载,web开发资源,技术博客
其次,JS 中,调用构造器后,对象并不是它 原型 的一份拷贝,而是被 到了原型上。RPT易塔云建站-模板下载,web开发资源,技术博客
我们首先看一段代码:
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
在执行这段代码之前,有个东西是一直存在的,就是别人所说的 “原型的原型”,如下图:RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
一、开始之前RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
左边的圆形是Object的构造函数,就是我们一般使用 var obj = new Object()时最普通的构造函数。RPT易塔云建站-模板下载,web开发资源,技术博客
右边的方形是Object的prototype,这个东西没有名字(虽然大家都要知道)。RPT易塔云建站-模板下载,web开发资源,技术博客
左 → 右 箭头,意味着 Object 有一个属性叫做 prototype ,这个属性指向右边的方块。RPT易塔云建站-模板下载,web开发资源,技术博客
右 ← 左 箭头,意味着 右边的 无名 的 constructor 属性,是左边的 Object 函数。
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
这些东西在上面代码运行之前就一直存在着。RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
二、构造函数RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
好的,我们开始运行第一行代码,会生成一个叫 Person 的构造函数,而这个函数的 prototype 属性,指向的就是它的 prototype 。如图:RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
Person 与 Person.prototype 之间的关系,与 Object 与 Object.prototype 之间的关系类似,RPT易塔云建站-模板下载,web开发资源,技术博客
不同的是,Person.prototype 会通过 __proto__ 指向 Object.prototype。RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
接下来我们看,我们在 Person.prototype 上添加了一个方法,于是这个方块有了 sayName 。
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
三、new 调用构造器RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
我们new了一个Person的实例,使用new这个关键字的时候,js编译器会做4件事:
①. 创建一个薪的空对象;RPT易塔云建站-模板下载,web开发资源,技术博客
②. 把这个对象链接到原型对象上,将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);RPT易塔云建站-模板下载,web开发资源,技术博客
③. 执行构造函数中的代码(为这个薪对象添加属性);RPT易塔云建站-模板下载,web开发资源,技术博客
④. 如果这个函数有返回值,就返回;否则,就返回新对象。
 
RPT易塔云建站-模板下载,web开发资源,技术博客
如上图所示,我们创建了一个新的person1 空对象,然后把 person1 通过 __proto__ 指向了原型对象,指向构造函数中的代码,person1 就会获得一个叫做name的属性,最后返回。RPT易塔云建站-模板下载,web开发资源,技术博客
person1 上有sayName这个方法吗?没有,就顺着person1的__proto__网上找,找到Person.prototype有,那么执行这个方法。RPT易塔云建站-模板下载,web开发资源,技术博客
这个方法内部使用了this.name ,那么this只想什么?RPT易塔云建站-模板下载,web开发资源,技术博客
我们需要看sayName的call this,是person1调用的sayName,隐式调用,this就指向person1,而person1的name就是Chris。RPT易塔云建站-模板下载,web开发资源,技术博客
是不是觉得很神奇,最后调用时候使用的属性和方法都是我们希望使用的那个,person1.sayName('Hello')看似很容易理解,JS初学者都能很容易说出最后输出结果,但是这其中的过程,恐怕只有理解了原型和原型链才能真正说明白。RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
明白了这些之后,我们看几个相等关系:
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
RPT易塔云建站-模板下载,web开发资源,技术博客
问题:console.log(person1.constructor)是什么的呢?怎么找到的呢?

评论

  • 匿名