[面试]从新奇的角度看手写new实现
前言
写这篇文章的本意是记录我脑海中闪过的一丝奇思妙想,与大家进行分享。欢迎大家和我一起讨论,越激烈越好。
我对面向对象不是很熟,小菜鸡,如果有写错,请一定批评我。
在面试的时候,我们经常会听到面试官和我们说,手写一个new实现吧。
就直接梭哈,4步走
- 创建一个空的简单JavaScript对象
- 将构造函数的prototype设置为空对象的原型
- 将构造函数的this,绑定到空对象上
- 判断是否构造函数返回了一个对象,如果返回了对象,那么就直接返回生成的那个对象,不然就返回这个新对象。
背起来代码也就几行,那么就背一下就完事了吗?
本来在写一个原型链的文章,然后写完工厂函数,到了构造函数,想到new,我就默认自己开始想这个代码,想这个步骤。我就想到为什么我们要干这些???
这块可能要涉及到一些原型链的东西(还有面向对象的一些东西),如果不太懂,可以先看着,等我后面写原型链。
首先,我们先来慢慢的想几个问题。(问题是连续的,不要跳过)。
- new是用来干什么的,我们为什么要用new?
MDN: new
运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
是用来创建对象类型或者具有构造函数的内置对象(这个先不说,其实就是指的是class)的实例.
那么如何理解?如果学过面向对象编程,就会知道class,知道封装。
为了更好理解,这里引入一个新的概念"工厂函数"。熟悉的大佬们,肯定是不用介绍了,但是这里还是啰嗦一下,为那些和我一样的小白讲一下。
工厂函数
例如:
function person(name, age) { var person = {}; person.name = name; person.age = age; return person; } let person1 = person("小明", 19); let person2 = person("小红", 20); console.log(person1, person2);
类似于上面的函数就被称为"工厂函数", 当我调用这个工厂函数的时候,这个函数就会在内部为我们创建一个对象,并在这个对象上创建一些对象属性,并将这个对象返回。就像一个流水线一样,按步骤执行,产出相同"类型"的"产品"。
"工厂"函数的理解:
- 它是一个函数
- 它用来创建对象
- 它就像工厂一样,生产出来的函数都是"标准件"。
那么现在来假设一个场景,我们现在在工厂的生产线上生产的是两个类型的产品,比如是猫布偶和狗布偶,并且它们都有一个功能是“发出叫声”, 那么现在它们两个就都需要一个零件 ===> 发声器(不区分叫声,叫声属于程序,不归生产线管)。那么我们是去搞两条生产线,一条去生产猫的,一条去生产狗的。还是就搞一条生产线呢?
当然是选择后面的了对吧!!!
这样子其实就是什么?就是功能抽离。将功能抽离到上一层。当我们一次一次的"抽离"功能,一次一次的"组装"。 注意这里的"抽离"和"组装"。
那么现在再回去看我们之前写的"工厂函数".是不是发现它并没有一个抽离和组装的过程,就像是直接凭空出现。(贫穷的想象,不知道怎么描述了)。
所以,为了更加细致,更加向面向对象靠拢,所以有了构造函数。
这块我搜索为什么会有构造函数,搜不到emmm
好,第二个问题。
- 构造函数干了什么事情?或者说 new 干了什么事情。
别问,问就是4步走
- 创建一个空的简单JavaScript对象。
工厂函数的第一步,给你一个空的"底座",然后送上流水线。
- 将构造函数的prototype设置为空对象的原型
将"上一层"生产的模块(封装好的模块)交给你
- 将构造函数的this,绑定到空对象上,并执行构造函数
基于"上一层"的模块,和自己这一层的"零件"(属性和方法),组装成我们这一层的"模块".
那我肯定是要将零件组织到这个模块上啊,所以就必须的将目标"强制的绑定"到已有的这个模块上啊。
- 判断是否刚才执行构造函数返回了一个对象,如果返回了对象,那么就直接返回生成的那个对象,不然就返回我们生成的这个对象。
如果这个流水线(构造函数),就根本不用上面的模块,那么就返回自己零件组织的模块,如果用到了就生成和模块组装后的那个。(抱歉,这块可能有点想当然了,大家可以理解着记忆)。
最后,上代码
function _new(fn, ...args) { // 第一步和第二步 let obj = Object.create(fn.prototype); // 第三步 let value = fn.call(obj, ...args); // 第四步 return value instanceof Object ? value : obj; }
Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。
结尾
星星之火可以燎原,希望我的一点奇思妙想可以帮助大家更好的理解 在new
一个构造函数的时候发生了什么,我们应该如何去手写它,如何不让它是一叶孤舟,让它更好的与其他知识连接。
不管怎样,总会有办法的!!!
闲聊
之前自学前端,一直感觉自己没有一个体系的学习成长路线,一直自己瞎跑,到处踩坑,到处碰壁。今天又想了想,发现这不就是从小长大的我吗,一路长大磕磕绊绊,培养了自己坚韧的内心,前端学习也是这样,一路的磕磕绊绊也培养了我在学前端的"坚韧"的性格。所以,感谢困难,它让我迎来更好的自己。大家找工作加油。