• 作者:老汪软件技巧
  • 发表时间:2024-12-15 17:04
  • 浏览量:

引言

JS 中,new操作符是一个非常重要的特性,它允许我们创建对象并调用构造函数来初始化这些对象。在面试中,手写new是一个非常常见的考点。本文将深入探讨new操作符的工作原理,并通过手写实现一个类似new操作符功能的函数。

56665.jpg

new操作符的作用

在JS中,使用new操作符可以创建一个新的对象,并将这个对象的原型链链接到构造函数的原型对象上。同时,它还会执行构造函数,并将构造函数中的this 绑定到新创建的对象上。这样,我们就可以通过构造函数来初始化新创建的对象的属性和方法。

例如,以下是使用new操作符创建一个Person对象的示例,来帮助我们理解new到底都干了些什么事:

function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.sayName=function(){
    console.log(this.name);
}
// new 实例化运算符 
// 1. 创建一个空对象 {} 和 Person 没有血缘关系 
// {} __proto__  Object.prototype
// 2. 手动的__proto__ 指向 Person.prototype
// 3. 构造函数 this 指向 {} 执行,给{}赋值
const zzz=new Person('zzz',20);

在这个例子中,我们定义了一个构造函数Person,它接受两个参数name和age,并在构造函数内部将这两个参数赋值给新创建的对象的属性。同时,我们还在Person的原型对象上定义了一个方法sayName ,这个方法可以打印出对象的name属性。最后,我们使用new操作符创建了一个Person对象,并调用了它的sayName方法。

new操作符的工作原理

了解了new操作符的作用后,我们来深入探讨一下它的工作原理。当我们使用new操作符时,JS引擎会执行以下几个步骤:

创建一个空对象 {}将这个新对象的原型链链接到构造函数的原型对象上执行构造函数,并将构造函数中的this 绑定到新创建的对象上如果构造函数返回一个非原始值(即对象或函数),则返回这个值。否则,返回新创建的对象手写new

下面我们来手写一个new:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function () {
    console.log(this.name);
}

前端高频面试题_前端手写代码大全_

// 不设置形参 使用arguments 获取参数 function objectFactory() { // arguments 所有参数 类数组 // console.log(arguments,arguments.length); const obj = new Object(); // 1. 空对象创建 // arguments 类数组 没有shift 方法 借给 arguments shift方法 // [].shift.call(arguments) 将类数组 转为数组 使用 shift const Constructor = [].shift.call(arguments) // console.log(Constructor); // 2. 手动的__proto__ 指向 Person.prototype obj.__proto__ = Constructor.prototype; // 3. this 指向 apply 第二项是数组 const result = Constructor.apply(obj,arguments); // console.log(obj); // 4. 如果构造函数返回的是一个对象,则返回这个对象;否则返回新创建的对象 return result instanceof Object ? result : obj; } // 传参为函数名和各项值 let awei = objectFactory(Person,'zzz',20) console.log(zzz.name); // zzz zzz.sayName(); // zzz

在这个实现中,我们首先创建了一个空对象obj,然后将这个对象的原型链链接到构造函数的原型对象上。接着,我们使用apply方法执行构造函数,并将构造函数中的this绑定到新创建的对象上。最后,返回对象obj。

步骤分析

在上面的方法中使用到的一些方法,我会在下面做一下解释:

arguments:这是一个伪数组(类数组对象), 它包含了传递给函数的所有参数。arguments 只能在函数体内访问[].shift.call(arguments):shift()定义在Array.prototype上,只能由数组使用。arguments是伪数组,没有shift()方法。我们通过一个空数组[ ]来调用shift(),并使用call()绑定到arguments上来让伪数组使用shift()方法。将函数名赋给Constructorobj.__proto__ = Constructor.prototype:将这个新对象的原型链链接到构造函数的原型对象上,保证实现new的功能Constructor.apply(obj,arguments):使用apply确定函数Constructor的this指向创建的新对象obj,将剩下的arguments作为参数一起传给函数Constructor。这里绑定this使用的是apply,apply可以将所有参数用数组的方式一起传送,call只能一个一个传值。最后,如果构造函数返回的是一个对象,则返回这个对象;否则返回新创建的对象

至此,一个简单的手写new就完成了!!!

总结

通过深入解析new操作符的机制并手写实现一个简易版本。手写new作为面试中一道常考题,希望这篇文章能够帮助到你。

sdffs.jpg