当前位置: 首页 > 科技观察

深入理解New运算符

时间:2023-03-17 22:31:51 科技观察

前言我们在实例化一个函数的时候,需要用到new运算符来实现。那么,你清楚它的底层实现原理吗?原理分析下面用一个具体的例子来看看new之后的next函数能做什么,如下:functionPerson(name,age){this.name=name;这个。年龄=年龄;this.height="175cm";this.bodyWeight="65kg";return"someanything";}Person.prototype.dailyExercise="300kcal";Person.prototype.printBodyWeight=function(){console.log(this.name+"weightis:"+this.bodyWeight);};接下来,我们使用new关键字来实例化Person函数,我们发现实例化之后,我们可以访问到:函数内部函数原型上的属性constperson=newPerson("了不起的程序员","22");console.log(person.age);console.log(person.bodyWeight);console.log(person.dailyExercise);person.printBodyWeight();眼尖的开发者你可能已经注意到我们的构造函数返回了一个字符串,它是一个原始类型。如果我们返回一个对象会发生什么?functionPerson(name,age){return{bodyWeight:this.bodyWeight};}再次运行代码,我们发现只能访问我们在构造函数中返回的属性。构造函数中声明的其他属性和原型上安装的属性是不可访问的。实现思路经过前面的分析,我们知道函数new完成后会返回一个新的对象,构造函数中的所有属性和函数原型上的所有属性都挂载在这个对象上。我们在实现的时候还需要创建一个新的对象,这个对象需要包含构造函数中的属性,所以我们可以使用apply方法为这个对象添加新的属性。在深入理解原型链与继承一文中,我们知道实例的__proto__属性会指向构造函数的原型。这样的关系建立之后,实例就可以访问原型上的属性了。有了这些知识点作为铺垫,我们就可以写出这个模拟函数了,如下所示:创建一个对象来存放构造函数的属性从arguments中取第一个参数,也就是调用时构造函数指向new的原型object通过__proto__赋给构造函数的原型,并通过apply方法改变构造函数的this点,从而将构造函数内部的属性添加到新建的对象中,判断构造函数是否有返回值和返回值并且它的类型是对象或者函数,返回构造函数的返回值,否则返回我们新建的对象functioninstantiateFactory(){constobj={};constConstructor=[].shift.call(arguments);obj.__proto__=Constructor.prototype;constresult=Constructor.apply(obj,arguments);if(result&&(typeofresult=="object"||typeofresult=="function")){返回结果;}返回对象;}测试用例我们通过原理分析中的例子来验证我们实现的工厂函数是否可以正确执行。constfactory=instantiateFactory(Person,"了不起的程序员","22");console.log(factory.age);console.log(factory.bodyWeight);console.log(factory.dailyExercise);factory.printBodyWeight();假设函数没有返回值或者返回值为字符串类型,执行结果如下:当函数返回值为对象时,执行结果如下: