面了10分钟就结束了,前端三道题都是很有难度的题一个没答出来,后端我也讲的不是很好,感觉是自微软面试以来最难的,我只能自认被上课了,然而区区一个外包面试却这么的难,我觉得不行!
难度:中等偏上
我百度加上自己理解尝试写的答案,不对的请务必指正
前端部分:
React中SetState原理
我们平时需要修改state时,需要通过调用SetState对它进行修改,而不是直接修改state,因为直接修改state只是修改了它的值,并不能将视图重新渲染。而SetState除了会更新状态的值,还会重新更新组件,对相关的视图重新进行render,相当于把生命周期中[更新]这个过程调用了一遍。
如果在短时间内执行多个SetState操作,这些状态更新将会被异步的加入一个更新队列,成为批量更新模式,只有在事件结束之后再把这些状态更新一次性进行render,这样就把虚拟DOM和真实DOM的操作数降到最小从而提高性能。
如果只进行一次更新操作,则不会进入批量更新模式,它会直接渲染视图。
ES2022有哪些新特性
1.类相关
加入了公共属性,就是比如React中状态的设置可以直接在类里面进行定义,而无需在构造函数里。在公共属性前面加上static即为静态公共属性。例如:state = { count: 0 };
加入了私有属性/函数,在属性/函数前面加上#就是私有的,只能在类里面自己调用。例如:#privateSlot #nonStaticPrivateAccessor(value) {}
加入了静态初始化块,该代码块在类的声明期间就被调用。例如: static{ }
2.一些关键字
in 用于检查一个对象中是否具有某个私有属性,例如: #privateSlot in obj
at 用于根据索引返回集合中的某个值,例如:[‘a’, ‘b’, ‘c’].at(0)
使用await调用异步函数, 例如: await fetch(‘https://example.com’)
error.cause 用于新建一个错误,相当于抛异常, 例如:throw new Error(‘Something went wrong’, {cause: error})
Object.hasOwn 用于判断一个对象是否包含某属性: 例如: Object.hasOwn(example, ‘property’)
3.正则表达式
加入了/d.exec() 可以使匹配对象带有indices数组
个人感觉这些改动使js更像java/c#这种面向对象语言
ES6的class通过ES5是怎么实现的
在ES5中,构造器就是一个function,相当于一个类,在构造器的prototype上面定义function就相当于给这个类添加函数,通过new构造器的方式进行实例化。
function A(prop){
this.prop = prop
}
A.prototype.method1 = function(){
}
const a = new A(0)
a.method1()
ES6类的底层其实也是原型链,对上面的内容进行了一个包装,相当于一个语法糖。但有所不同的是一个ES6的类本质上是一个function,这个function里面有一个跟它同名的局部function作为构造器,当new这个构造器,类的这个function返回他自己的构造器达到创建对象的目的。构造器里面调用了一个_classCallCheck()用于检测防止用户不通过new的方式直接调用构造器。
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var A = function () {
function A(prop) {
_classCallCheck(this, A);
this.prop = prop
}
return A;
}();
类的属性和函数本质上是通过调用Object.defineProperty()函数来添加, 这个函数作用是直接在一个对象上定义一个新属性,或者修改一个对象的现有属性。
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var A = function () {
function A(prop) {
_classCallCheck(this, A);
this.prop = prop
}
_createClass(A, [{
key: "method1",
value: function method1() {
}
}]);
return A;
}();
extends的本质其实就是将父类的对象作为参数传入子类,并在子类里面定义_inherits函数:子类原型对象的原型,指向父类的原型对象,即B.prototype.proto = A.prototype, 并且子类的原型指向父类,即 B.proto = A,保证了静态属性也能访问到.
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var A = function () {
function A(prop) {
_classCallCheck(this, A);
this.prop = prop
}
_createClass(A, [{
key: "method1",
value: function method1() {
}
}]);
return A;
}();
var B = function (_Parent) {
_inherits(B, _Parent);
function B() {
_classCallCheck(this, B);
return _possibleConstructorReturn(this, (B.__proto__ || Object.getPrototypeOf(B)).call(this));
}
return B;
}(A);
后端部分:
你平时是以什么方式进行开发的?