GithubHelp home page GithubHelp logo

interview's Introduction

HTML & CSS

这快被问的内容比较少,重点从布局入手,比如单位、盒模型、定位、响应式布局等知识点。

CSS:BFC、权重

JavaScript

对于JavaScript不限于初级、中级、高级;包括原型与原型链、继承、事件循环、作用域、ES6语法、垃圾回收与内存泄漏等。还有很多,自己整理。

网络通信

网络通信少不了TCP/IP、UDP、HTTP、HTTPS、Websocket、DNS解析、浏览器缓存、CDN缓存这些。

前端框架

Vue

Vue经典面试题不必多说,深入探究其原理很有必要,除了一些经典的原理以外,可以对每个小知识点的原理配合源码实现来整理回答。其次可以理解其**或者一些设计模式的实现,如响应式依赖的观察者模式。。。

再者,对于其生态的其他技术或者前沿技术,要掌握和了解。对于Vue来说,Router和Vuex必不可少,其次如vue-cli、pinia等要了解。

最后Vue3.0已经变为默认版本了,这个必须要掌握了,并能说出相较于2.0做了哪些改进、api的变动、原理的优化等。

例如:Vue diff、响应式原理(准确的说,应该叫数据响应式原理)、双向绑定原理、Vue3.0 新特性。。。

数据响应式原理和双向数据绑定

React

后续学习补充。(去上海的话必学😄)

工程化

webpack

如loader和plugin的原理,编写loader和plugin的流程、webpack构建流程、热更新原理、性能优化等。

打包界的新宠:vite(rollup)、Esbuild等

Babel & Polfill

这两个东西作为前端基建的基础,几乎在任何前端项目中都能用到;但是我们日常开发很少碰到他们,即使碰到了也只是参考下官网对特定的需求,进行配置而已,这样是远远不够的。

这里先放一些比较好的文章,后续补充学习归纳。

Polyfill和转译器

[前端基建]带你在Babel的世界中畅游

用了babel还需要polyfill吗

浏览器原理

对于后端来说,瓶颈在数据库;对于前端来说,性能显而在浏览器,因此对于浏览器原理的理解也是不可或缺的。比如我们在开发一个WebGL相关的项目时,不了解浏览器的渲染压力,疯狂绘制,这样很容易导致浏览器的崩溃。

这里列举一些:浏览器渲染原理、浏览器本地存储(chrome 内存查看)、浏览器同源策略、浏览器事件机制、垃圾回收机制、浏览器安全、进程与线程(js主线程、UI线程、网络线程。。。)、浏览器缓存、浏览器组成等等。

算法

前端对算法的考察大部分为easy和medium,都是比较常用的,但是一定要做出来才行。

基础算法:排序、递归、链表、动态规划、贪心等等。

2022年疫情原因,行情不好,导致招聘也发生了变化;

  • HC下降 —— 缩招
  • 面试难度上升 —— 算法、手写类变多、是否热点项目经验变多
  • 各家采用人才库 —— 珍惜每一次的面试机会,试错成本变高
  • 注重实战经验 —— 知识面,注重已有经验

中高级前端工程师必备门槛

interview's People

Contributors

dawson66 avatar

Watchers

 avatar

interview's Issues

JavaScript继承

原型链继承

function Person() {
  this.name = 'dawson'
}

Person.prototype.getName = function () {
  return this.name;
}

function Student() {}

// 原型链继承:子类构造函数指向父类实例
Student.prototype = new Person();

const student = new Student();

console.log(student.getName());  // dawson

// 引发的问题?

问题

  1. 子类指向的是一个固定的实例对象,即所有Student实例都共享这个Person实例,它们操作的是同一个引用对象。
function Person() {
  this.name = 'dawson';
  this.hobbies = ['backetball', 'football'];
}

Person.prototype.getName = function () {
  return this.name;
}

Person.prototype.addHobbies = function (...args){
  this.hobbies.push(...args);
}

function Student() {}

Student.prototype = new Person();

const student1 = new Student();
const student2 = new Student();
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies);  // ['backetball', 'football', 'music', 'dance']

  1. 子类创建时,不能向父类传参,因为子类实例化时,父类已经实例化好了。
细想一下,子类实例化时,通用性属性一般super调用父类的构造函数来为子类初始化,然而,子类构造函数原型指向一个固定的对象,怎么也做不到传值的操作!

构造函数继承

function Person(options) {
  this.age = options.age;
  this.name = 'dawson';
  this.hobbies = ['backetball', 'football'];
}

Person.prototype.getName = function () {
  return this.name;
}

Person.prototype.addHobbies = function (...args){
  this.hobbies.push(...args);
}

function Student(options) {
  // 所谓的构造函数继承就是在子类的构造函数中调用父类的构造函数并指定this
  Person.call(this, options)
}

const student1 = new Student({age: 20});
const student2 = new Student({age: 88});
console.log(student1.age);  // 20
console.log(student2.age);  // 88
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // Uncaught TypeError: student1.addHobbies is not a function

// 解决了什么问题?
// 1. 解决了原型链继承的传参问题

// 引发了什么问题?
// addHobbies报错说明原型上没有此方法,即子类未继承父类原型链上的属性和方法;那么你可能会说,可以将方法挂载到属性上而不是原型上,没错,这样是可以的
// 但是会引发一个问题,就是子类每次实例化时都会重复创建相同的方法,如addHobbies,这样就丧失了原型链或者面向对象的意义,因此引出下面思考

// 思考:未继承原型链上的属性,那么我们怎么才能继承父类原型链上的属性呢?

组合继承

function Person(options) {
  this.age = options?.age || 20;
  this.name = 'dawson';
  this.hobbies = ['backetball', 'football'];
}

Person.prototype.getName = function () {
  return this.name;
}

Person.prototype.addHobbies = function (...args){
  this.hobbies.push(...args);
}

function Student(options) {
  Person.call(this, options);
  this.gender = options.gender;
}

// 借用原型继承的优点,子类原型指向父类实例,虽不能传参,但是能够继承原型链上的属性
Student.prototype = new Person();
// 需要修复构造函数指向,Student实例constructor属性需要指向其构造函数
// student1.constructor == Student   Student.prototype.constructor == Student
Student.prototype.constructor = Student;

const student1 = new Student({age: 20, gender: 'male'});
const student2 = new Student({age: 88, gender: 'female'});
console.log(student1);
console.log(student1.age);  // 20
console.log(student2.age);  // 88
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // ['backetball', 'football', 'music']

组合继承已经能够实现对象的继承问题,算是一种解决方案了,但是还不够完美。如果你将student实例打印并查看的话,你会发现,属性不仅在实例中有,在原型对象上也有,因为我们的父类构造函数被调用了两次!那么如何减少一次构造函数的调用呢?


寄生式组合继承

// 寄生式组合继承作为ES6之前的 继承的 较好实现
function Person(options) {
  this.age = options?.age || 20;
  this.name = 'dawson';
  this.hobbies = ['backetball', 'football'];
}

Person.prototype.getName = function () {
  return this.name;
}

Person.prototype.addHobbies = function (...args){
  this.hobbies.push(...args);
}

function Student(options) {
  Person.call(this, options);
  this.gender = options.gender;
}

function F(){

}

// 中间加一层,子类原型指向F实例,F实例原型之乡Person的原型,实现原型链的访问
F.prototype = Person.prototype;
// 这里试想一下,Student.prototype = Person.prototype 行不行? 为何中间非要加一层?
Student.prototype = new F();
// 别忘了,constructor的正确指向
Student.prototype.constructor = Student;


const student1 = new Student({age: 850, gender: 'male'});
const student2 = new Student({age: 88, gender: 'female'});
console.log(student1);
console.log(student1.age);  // 20
console.log(student2.age);  // 88
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // ['backetball', 'football', 'music']

class继承

class Person {
  constructor(options){
    this.age = options?.age || 20;
    this.name = 'dawson';
    this.hobbies = ['backetball', 'football'];
  }

  getName() {
    return this.name;
  }

  addHobbies(...args){
    this.hobbies.push(...args);
  }
}

class Student extends Person {
  constructor(options){
    super(options)
    this.gender = options.gender
  }
}

const student3 = new Student({age: 890, gender: 'male'})
console.log(student3);

JavaScript函数方法bind,call和apply的实现

bind

先来看一个例子

// 例一
var name = 'global'

let obj = {
  name: 'dawson'
}

function getName() {
  return this.name;
}

const copyGetName = getName.bind(obj)
console.log(getName());      // global
console.log(copyGetName());  // dawson

// 例二
function add(a, b, c) {
  return a + b + c;
}
const copyAdd = add.bind(null, 1);
console.log(copyAdd(2, 3));   // 6

结论:

  • 返回一个函数
  • 绑定this
  • 柯里化特性(偏函数)
  • 构造函数特性
// 实现上述三点,第四点是最难的,也请思考!
Function.prototype._bind = function (context) {
  if (typeof this !== 'function') {
    throw new Error('bind只能被函数调用')
  }
  const fn = this;
  const args = Array.prototype.slice.call(arguments, 1);
  return function () {
    const bindArgs = Array.prototype.slice.call(arguments);
    return fn.call(context, ...args, ...bindArgs);
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.