javascripts进阶_自己实施javascripts新操作员致命的前端面试问题

javascripts进阶

The concept of the new operator is from class-based object-oriented languages such as C++ and Java. It is used to create an instance or object of a class and in general, it mainly does two things: Instantiating — allocating spaces in memory for the object being created, and Initialization — executing the constructor method and initializing the object (e.g. its member variables and member functions).

运算符的概念来自于基于类的面向对象的语言,例如C ++和Java。 它用于创建类的实例或对象,通常,它主要做两件事:实例化—为要创建的对象在内存中分配空间;以及初始化—执行构造函数方法并初始化对象(例如,其成员变量)和成员函数)。

For JavaScript, it is not a class-based language like Java, it is prototype-based, so its new operator does its very specific things and is very different from the new operator in Java.According to MDN:

对于JavaScript,它不是基于类的语言如Java,它是基于原型,所以它的新的运营商做了非常具体的东西,是从Java.According到新的运营商非常不同的MDN

The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

新的运算符使开发人员可以创建用户定义的对象类型或具有构造函数的内置对象类型之一的实例。

For example, we create a constructor function below and use the new operator to create an instance of this constructor function:

例如,我们在下面创建一个构造函数,并使用new运算符创建该构造函数的实例:

function Employee(name) {
this
.name = name;
}
const employee
= new Employee('Mike');

Employee() is just a normal function in JS, and when we use the new operator in front of it, it becomes a “constructor function”. Now an object of the constructor is created, and its reference is assigned to the constant variable employee.

Employee()只是JS中的一个普通函数,当我们在其前面使用new运算符时,它便成为“构造函数”。 现在,创建了构造函数的对象,并将其引用分配给常量变量employee

As per MDN, the new operator does the following four things:

按照MDN操作员将执行以下四项操作:

Creates a blank, plain JavaScript object;

创建一个空白的纯JavaScript对象;

Links (sets the constructor of) this object to another object;

将这个对象链接(设置其构造函数)到另一个对象;

Passes the newly created object from Step 1 as the this context;

步骤1中新创建的对象作为this上下文传递;

Returns this if the function doesn't return an object.

如果函数不返回对象,则返回this值。

Also,

也,

Creating a user-defined object requires two steps:

创建用户定义的对象需要两个步骤:

Define the object type by writing a function.

通过编写函数定义对象类型。

Create an instance of the object with new.

使用new创建对象的实例。

With the official definition in hand, let’s implement the new operator ourselves.

有了正式定义,让我们自己实现新的运算符。

First, create a function named New. It takes a couple of parameters and the first parameter is the constructor function being passed in. We use the rest syntax to collect the rest parameters into an array named args.

首先,创建一个名为New的函数 它需要几个参数,第一个参数是传入的构造函数。我们使用rest语法剩余参数收集到名为args的数组中。

function New(constructor, ...args) {
}

对于步骤1-创建一个空白的纯JavaScript对象 (For Step 1 — Creates a blank, plain JavaScript object)

Let’s create an empty object in the function body:

让我们在函数体中创建一个空对象:

function New(constructor, ...args) {// 1. Create a new empty objectconst obj = {};
// const obj = new Object();
// const obj = Object.create(null);

}

Note there are three ways to create an empty object:

请注意,有三种创建空对象的方法:

const obj = {};
const obj = new Object();
const obj = Object.create(null);

So I put the other two in the comments for reference.

因此,我将其他两个放在注释中以供参考。

现在,第2步-将这个对象链接(设置其构造函数)到另一个对象 (Now Step 2 — Links (sets the constructor of) this object to another object)

This can be done through one assignment statement:

这可以通过一个赋值语句来完成:

function New(constructor, ...args) {// 1. Create a new empty objectconst obj = {};
// const obj = new Object();
// const obj = Object.create(null);
// 2. Assign the constructor’s prototype property to the new empty object’s __protp__ property
obj.__proto__ = constructor.prototype;
// Object.setPrototypeOf(obj, constructor.prototype);
}

We set the reference of the constructor’s prototype to the new object’s __proto__ property. Here you could also use Object.setPrototypeOf() and it is normally recommended. Below these two lines do the same thing:

我们将构造函数原型的引用设置为新对象的__proto__属性。 在这里,您还可以使用Object.setPrototypeOf() ,通常建议这样做。 在这两行下面执行相同的操作:

obj.__proto__ = constructor.prototype;
Object.setPrototypeOf(obj, constructor.prototype);

This one single assignment statement sets up the prototype chain for the object obj. It is crucial because it proves that objects in JS rely on prototype and the prototype chain. This is completely different from its “brother” Java (JS was meant to be named “LiveScript” when created in the 1990s, then it was renamed to “JavaScript” because Java came out at that time and was the hottest programming language).

这个单一的赋值语句为对象obj设置了原型链。 之所以至关重要,是因为它证明了JS中的对象依赖原型和原型链。 这与它的“兄弟” Java完全不同(JS在1990年代创建时曾被命名为“ LiveScript”,然后由于当时Java诞生并且是最热门的编程语言而被重命名为“ JavaScript”)。

进入步骤3-将步骤1中新创建的对象作为“ this”上下文传递 (Moving on to Step 3 — Passes the newly created object from Step 1 as the `this` context)

Now we need to execute the constructor function passed to our New() function:

现在我们需要执行传递给New()函数的构造函数:

function New(constructor, ...args) {// 1. Create a new empty objectconst obj = {};
// const obj = new Object();
// const obj = Object.create(null);
// 2. Assign the constructor’s prototype property to the new empty object’s __protp__ property
obj.__proto__ = constructor.prototype;
// Object.setPrototypeOf(obj, constructor.prototype);
// 3. Execute the constructor, set obj as the context of `this` when the constructor runs
const result = constructor.call(obj, args);

}

We do this by using the call() method and save the result in a constant variable result.

我们通过使用call()方法来做到这一点,并将结果保存在一个常量变量result中

最后进行第4步-如果函数未返回对象,则返回`this` (Finally for Step 4 — Returns `this` if the function doesn’t return an object)

We will check if the result of calling the constructor in Step 3, if it is an object type, then return it. If not, we will return obj as the new object:

我们将检查步骤3中调用构造函数的结果是否为对象类型,然后返回它。 如果没有,我们将obj作为新对象返回:

function New(constructor, ...args) {// 1. Create a new empty objectconst obj = {};
// const obj = new Object();
// const obj = Object.create(null);
// 2. Assign the constructor’s prototype property to the new empty object’s __protp__ property
obj.__proto__ = constructor.prototype;
// Object.setPrototypeOf(obj, constructor.prototype);
// 3. Execute the constructor, set obj as the context of `this` when the constructor runs
const result = constructor.call(obj, args);

// 4. Return the objectreturn typeof result === 'object' ? result : obj;
}

All done, let’s test it out. We create an Employee() constructor function and it receives an array of parameters:

全部完成,让我们对其进行测试。 我们创建一个Employee()构造函数,它接收一个参数数组:

function Employee(args) {
this
.name = args[0];
this.title = args[1];
console.log('constructor, this = ', this);
}

Now we can use our own New() function to create an object based on the constructor Employee():

现在我们可以使用自己的New()函数基于构造函数Employee()创建一个对象:

const employeeA = New(Employee, 'Joe', 27);
console.log('employeeA = ', employeeA);

Run it and in the console, we can see:

运行它,然后在控制台中,我们可以看到:

Image for post

A new object employeeA was successfully created using our New() function!

使用我们的New()函数成功创建了一个新对象employeeA

There are other ways to implement it and you can add more checks, please leave a comment if you have other versions.

还有其他实现方法,您可以添加更多检查,如果有其他版本,请发表评论。

翻译自: https://medium.com/weekly-webtips/implement-javascripts-new-operator-yourself-a-killer-frontend-interview-question-68468ad0a227

javascripts进阶

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值