美文网首页
前端JavaScript面试技巧

前端JavaScript面试技巧

作者: Mark同学 | 来源:发表于2019-12-06 10:32 被阅读0次

1-1 课程概述

  • 要做什么?——讲解前端 JS 基础面试题
  • 哪些部分?——JS 基础,JS-WEB-API,JS 开发环境
  • 使用技术?——JS,直指面试题

知识点介绍

基础知识(三座大山)
  • 原型 原型链
  • 作用域 闭包
  • 异步 单线程
JS API
  • DOM 操作
  • AJAX
  • 事件绑定
开发环境
  • 版本管理
  • 模块化
  • 打包工具
运行环境
  • 页面渲染
  • 性能优化

讲述方式

  • 以面试题引出知识点,深化知识点,举一反三

课程收获

  • 前端 JS 基础知识以及知识体系

1-2 前言

关于面试(分成三个阶段)

  • 基层工程师 - 基础知识
  • 高级工程师 - 项目经验
  • 架构师 - 解决方案

关于基础

  • 工程师的自我修养 - 基础
  • 扎实的基础会让你高效学习新技术

1-3 几个面试题

JS 中使用 typeof 能得到哪些类型?
考点:JS 变量类型

何时使用 ===,何时使用 ==?
考点:强制类型转换

window.onload 和 DOMContentLoaded 的区别?
考点:浏览器的渲染过程

用 JS 创建10个<a>标签,点击的时候弹出来对应的序号?
考点:作用域

简述如何实现一个模块加载器,实现类似 require.js 的基本功能?
考点:JS 模块化

实现数组的随机排序?
考点:JS 基础算法

思考

  • 拿到一个面试题,你第一时间看到的是什么?
    答:考点。(考的哪里)
  • 如何看待网上搜出来的永远也看不完的题海?
    答:不变应万变。(知识不变)
  • 如何对待接下来遇到的面试题?
    答:题目到知识再到题目。

第二章 JS基础知识

2-1 变量类型和计算

题目

JS 中使用 typeof 能得到哪些类型?
考点:JS 变量类型(6种),不能区分引用类型*

typeof undefined // undefined
typeof 'abc' // string
typeof 123 // number
typeof true // boolean
typeof {} // object
typeof [] // object
typeof null // object
typeof console.log // function

何时使用 ===,何时使用 ==?
考点:强制类型转换(==有类型转换,===没有)

JS 中有哪些内置函数?
考点:数据封装类对象

Object
Array
Boolean
Number
String
Function
Date
RegExp
Error

JS 变量按照存储方式区分为哪些类型,并描述其特点?
考点:值类型(分块存储) vs 引用类型(共享内存)
前者是值的拷贝,后者是引用的拷贝

如何理解 JSON?
答:JS 对象(同 Math)|| 数据格式

// 常用的方法有两个
JSON.stringify({a:10, b:20}); // 对象 => 字符串
JSON.parse('{"a":10,"b":20}'); // 字符串 => 对象

知识点

1.变量类型:值类型 vs 引用类型

  • 值类型
var a = 100;
var b = a;
a = 200;
console.log(b); // 100
  • 引用类型(对象、数组、函数),引用类型的设计是为了共享内存空间
var a = {age:20};
var b = a;
b.age = 21;
console.log(a.age); // 21

2.变量计算 - 强制类型转换

  • 字符串拼接
var a = 100 + 10;    // 110
var b = 100 + '10';  // '10010'
  • == 运算符
100 == '100' // true
0 == '' // true
null == undefined // true
  • if 语句
var a = true;
if (a) { // ... }
var b = 100;
if (b) { // ... }
var c = '';
if (c) { // ... }
  • 逻辑运算
console.log(10 && 0); // 0
console.log('' || 'abc'); // 'abc'
console.log(!window.abc); // true

2-5 原型和原型链

题目

如何准确判断一个变量是数组类型?

var arr = [];
arr instanceof Array; // true
typeof arr; // object,typeof 是无法判断是否是数组的

写一个原型链继承的例子?

// 动物
function Animal() {
  this.eat = function () {
    console.log('animal eat');
  }
}
// 狗
function Dog() {
  this.bark = function () {
    console.log('dog bark');
  }
}
Dog.prototype = new Animal();
// 哈士奇
var hashiqi = new Dog();
// 写一个封装 dom 查询的例子,演示原型链继承
function Elem(id) {
  this.elem = document.getElementById(id);
}

Elem.prototype.html = function (val) {
  var elem = this.elem;
  if (val) {
    elem.innerHTML = val;
    return this; // 链式操作
  } else {
    return elem.innerHTML;
  }
}

Elem.prototype.on = function (type, fn) {
  var elem = this.elem;
  elem.addEventListener(type, fn);
}

var div1 = new Elem('div1');
// console.log(div1.html());
div1.html('<p>hello imooc</p>').on('click', function () {
  alert('clicked');
});

描述 new 一个对象的过程?
考点:构造函数

  • 创建一个新对象
  • this 指向这个新对象
  • 执行代码,即对 this 赋值
  • 返回 this
function Foo(name, age) {
  this.name = name;
  this.age = age;
  this.class = 'class-1';
  // return this; // 默认有这一行
}
var f = new Foo('zhangsan', 20);

zepto (或其他框架)源码中如何使用原型链?

知识点

构造函数

function Foo(name, age) {
  this.name = name;
  this.age = age;
  this.class = 'class-1';
  // return this; // 默认有这一行
}
var f = new Foo('zhangsan', 20);

构造函数 - 扩展

var a = {} 其实是 var a = new Object() 的语法糖
var a = [] 其实是 var a = new Array() 的语法糖
function Foo(){...}其实是 var Foo = new Function(...) 
使用 instanceof 判断一个函数是否是一个变量的构造函数

原型规则和示例

5条原型规则:原型规则是学习原型链的基础
  1. 所有的引用类型(数组、对象、函数),都具有对象特性,即可以自由扩展属性(除了'null'以外)
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;
  1. 所有的引用类型(数组、对象、函数),都具有一个_proto_属性,属性值是一个普通的对象
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
  1. 所有的函数,都具有一个prototype属性,属性值也是一个普通的对象
console.log(fn.prototype);
  1. 所有的引用类型(数组、对象、函数),_proto_属性值指向它的构造函数的'prototype'属性值
console.log(obj.__proto__ === Object.prototype);
  1. 当试图得到一个引用类型(数组、对象、函数)的某个属性时,如果这个引用类型本身没有这个属性,那么会去它的_proto_(即它的构造函数的 prototype )中寻找
// 构造函数
function Foo(name, age) {
  this.name = name;
}
Foo.prototype.alertName = function () {
  alert(this.name);
}
// 创建实例
var f = new Foo('zhangsan');
f.printName = function () {
  console.log(this.name);
}
// 测试
f.printName();
f.alertName();

补充:循环对象自身的属性

var item
for (item in f) {
  if (f.hasOwnProperty(item)) {
    console.log(item);
  }
}

原型链(顶级原型 Object.prototype)

f.toString(); // 要去 f.__proto__.__proto__ 中去找

instanceof(用于判断引用类型属于哪个构造函数的方法)

解答

第三章 JS基础知识

闭包和作用域

题目

说一下对变量提升的理解?预解析
考点:变量定义和函数声明

说明 this 几种不同的使用场景?

// 作为构造函数执行
// 作为对象属性执行
// 作为普通函数执行
// call apply bind 

创建 10 个 <a> 标签,点击的时候弹出来对应的序号?

// 这是错误的写法!
var i, a;
for (i = 0; i < 10; i++) {
  a = document.createElement('a');
  a.innerHTML = i + '<br>';
  a.addEventListener('click', function (e) {
    e.preventDefault();
    alert(i);
  });
  document.body.appendChild(a);
}
// 这是正确的写法!
var i;
for (i = 0; i < 10; i++) {
  (function (i) {
    var a = document.createElement('a');
    a.innerHTML = i + '<br>';
    a.addEventListener('click', function (e) {
      e.preventDefault();
      alert(i);
    });
    document.body.appendChild(a);
  })(i);
}

如何理解作用域?

  • 自由变量
  • 作用域链,即自由变量的查找
  • 闭包

实际开发中闭包的应用?

// 实际开发中闭包主要用于封装变量,收敛权限
function isFirstLoad() {
  var _list = [];
  return function (id) {
    if (_list.indexOf(id) >= 0) {
      return false;
    } else {
      _list.push(id);
      return true;
    }
  }
}

// 使用
var firstLoad = isFirstLoad();
firstLoad(10); // true
firstLoad(10); // false
firstLoad(20); // true

知识点

执行上下文

console.log('a is...', a); // undefined
var a = 100;

fn('zhangsan'); // 'zhangsan' 20
function fn(name) {
  age = 20
  console.log(name, age);
  var age
}
  • 范围:一段 <script> 或者一个函数
  • 全局:变量定义、函数声明
  • 函数:变量定义、函数声明、this、arguments

this

this 要在执行时才能确认值,定义时无法确认
var a = {
  name: 'A',
  fn: function () {
    console.log(this.name);
  }
}
a.fn(); // this === a
a.fn.call({name: 'B'}); // this === {name: 'B'}
var fn1 = a.fn;
fn1(); // this === window
  • 作为构造函数执行
function Foo(name) {
  // this = {};
  this.name = name;
  console.log('this is...', this);
  // return this; 
}
var f = new Foo('zhangsan'); 
// this === f
  • 作为对象属性执行
var obj = {
  name: 'A',
  printName: function () {
    console.log('this is...', this);
  }
};
obj.printName(); 
// this === obj
  • 作为普通函数执行
function fn() {
  console.log('this is...', this);
}
fn();
// this === window
  • call apply bind (指定第一个参数是 this, 第二个参数是形参)
function fn(name) {
  console.log('name is...', name);
  console.log('this is...', this);
}
fn.call({x:100}, 'zhangsan');
// this === {x:100}
var fn = function (name) {
  console.log('name is...', name);
  console.log('this is...', this);
}.bind({x:100});
fn('zhangsan');
// this === {x:100}

作用域

// 无块级作用域
if (true) {
  var name = 'zhangsan';
}
console.log(name);

// 函数和全局作用域
var a = 100;
function fn() {
  var a = 200;
  console.log('fn ', a);
}
console.log('global ', a); // global  100
fn(); // fn  200
  • 没有块级作用域
  • 只有函数和全局作用域

作用域链

var a = 100;
function fn() {
  var b = 200;
  
  // 当前作用域没有定义的变量,即“自由变量”
  console.log(a);

  console.log(b);
}
fn();
var a = 100;
function fn1() {
  var b = 200;
  function fn2() {
    var c = 300;
    console.log(a);
    console.log(b);
    console.log(c);
  }
  fn2();
}
fn1();

闭包

闭包的使用场景
  • 函数作为返回值
function fn() {
  var a = 100;
  
  // 返回一个函数(函数作为返回值)
  return function () {
    console.log(a);
  }
}
// f1 被赋值为一个函数
var f = fn();
var a = 200;
f(); // 100
  • 函数作为参数传递
function fn1() {
  var a = 100;
  return function () {
    console.log(a);
  }
}
var f1 = fn1();

function fn2(fn) {
  var a = 200;
  fn();
}
fn2(f1);

解答

第四章 JS基础知识

异步和单线程

题目

同步和异步的区别是什么?分别举一个同步和异步的例子?

一个关于 setTimeout 的笔试题?

前端使用异步的场景有哪些?

知识点

什么是异步(对比同步)

  • 异步和同步最大的区别是有没有阻塞程序运行
异步
console.log(100);
setTimeout(function () {
  console.log(200);
}, 1000);
console.log(300);
// 执行顺序 100 300 200
同步
console.log(100);
alert(200); // 10秒钟之后点击确认,确认之前,300永远不会被打印
console.log(300);

何时需要异步

  • 在可能发生等待的情况
  • 等待过程中不能像 alert 一样阻塞程序运行
  • 因此,所有“等待的情况”都需要异步

前端使用异步的场景

  • 定时任务
  • 网络请求
  • 事件绑定
// AJAX 请求代码示例
console.log('start');
$.get('/api/data.json', function (data) {
  console.log(data);
});
console.log('end');
// <img> 加载示例
console.log('start');
var img = document.createElement('img');
img.onload = function () {
  console.log('loaded');
}
img.src = '/xxx.png';
console.log('end');
// 事件绑定示例
console.log('start');
document.getElementById('btn').addEventListener('click', function () {
  alert('clicked');
});
console.log('end');

异步和单线程

一次只能干一件事
  • 执行第一行,打印100
  • 执行 setTimeout 后,传入 setTimeout 的函数会被暂存起来,不会立即执行(单线程的特点,不能同时干两件事)
  • 执行最后一行,打印300
  • 待所有程序执行完,处于空闲状态时,会立马看有没有暂存起来的要执行
  • 发现暂存起来的 setTimeout 中的函数无需等待时间,就立即来过来执行
console.log(100);
setTimeout(function () {
  console.log(200);
});
console.log(300);
// 执行顺序 100 300 200

解答

第四章 JS-Web-API

5-1从基础到JSWebAPI

回顾 JS 基础知识

  • 变量类型和计算
  • 原型和原型链
  • 闭包和作用域
  • 异步和单线程
  • 日期、Math、各种常用API
特点:表面看来并不能用于工作中开发代码
内置函数:Object Array Boolean String ......
内置对象:Math JSON ......
我们连在网页弹出一句 hello world 都不能实现
JS 基础知识:ECMA 262 标准(规定 JS 的基础语法)
JS-Web-API:W3C 标准(规定浏览器提供给开发者操作页面的API和全局变量)

JS 内置的全局函数和对象有哪些?

  • window document

浏览器执行的JS = ECMA262 + W3C
Node.js = ECMA262 + IO

5-2 DOM

DOM = Document + Object + Model

题目

DOM 是哪种基本的数据结构?

DOM 操作的常用 API 有哪些?

DOM 节点的 attr 和 property 有何区别?

知识点

DOM 本质

  • 浏览器把拿到的 html 代码,结构化成一个浏览器能识别、JS 可操作的一个模型(JS 对象)。

DOM 节点操作

  • 获取 DOM 节点
var div1 = document.getElementById('div1'); // 元素
var divList = document.getElementsByTagName('div'); // 集合
console.log(divList.length);
console.log(divList[0]);

var containerList = document.getElementsByClassName('.container'); //集合
var pList = document.querySelectorAll('p'); // 集合
  • property [对象的属性]
var pList = document.querySelectorAll('p');
var p = pList[0];
console.log(p.style.width); // 获取样式
p.style.width = '100px'; // 修改样式
console.log(p.className); // 获取 class
p.className = 'p1'; // 修改 class 

// 获取 nodeName 和 nodeType
console.log(p.nodeName);
console.log(p.nodeType);
  • Attribute [标签的属性]


    屏幕快照 2019-12-06 下午9.27.18.png

DOM 结构操作


  • 屏幕快照 2019-12-06 下午9.32.16.png

  • 屏幕快照 2019-12-06 下午9.33.34.png

  • 屏幕快照 2019-12-06 下午9.33.17.png

5-8 BOM

BOM = Brower + Object + Model

题目

如何检测浏览器的类型?

拆解 URL 的各部分?

知识点

  • navugator
  • screen
屏幕快照 2019-12-06 下午9.41.14.png
  • location
  • history


    屏幕快照 2019-12-06 下午9.42.12.png

6-1 事件绑定

题目

编写一个通用的事件监听函数?

function bindEvent(elem, type, selector, fn) {
  if (fn === null) {
    fn = selector;
    selector = null;
  }
  elem.addEventListener(type, function (e) {
    var target;
    if (selector) {
      target = e.target;
      if (target.matches(selector)) {
        fn.call(target, e);
      }
    } else {
      fn(e);
    }
  });
}
// 使用委托
var div1 = document.getElementById('div1');
bindEvent(div1, 'click', 'a', function (e) {
  console.log(this.innerHTML);
});

// 不使用委托
var a1 = document.getElementById('a1');
bindEvent(a1, 'click', function (e) {
  console.log(this.innerHTML);
});

描述事件冒泡流程?

对一个无限下拉加载图片的页面,如何给每个图片绑定事件?

知识点

通用事件绑定

var btn = document.getElementById('btn1');
btn.addEventListener('click', function (event) {
  console.log('clicked');
});

function bindEvent(elem, type, fn) {
  elem.addEventListener(type, fn);
} 
var a = document.getElementById('link1');
bindEvent(a, 'click', function (e) {
  e.preventDefault(); //阻止默认行为
  alert('clicked');
})

事件冒泡

事件冒泡

事件委托

事件委托

6-4 AJAX

题目

手动编写一个 AJAX,不依赖第三方库?

跨域的几种实现方式?

知识点

XMLHttpRequest

var xhr = new XMLHttpRequest();
xhr.open("GET", "/api", false);
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      alert(xhr.responseText);
    }
  }
}
xhr.send(null);

状态码说明

跨域

  • 什么是跨域


  • JSONP


  • 服务端设置 http header



6-6 存储

题目

请描述一下 cookie, sessionStorage 和 localStorage 的区别?

知识点

cookie

  • 本身用于客户端和服务端通信
  • 但是它有本地存储的功能,于是就被“借用”
  • 使用 document.cookie = ...获取和修改即可
  • 只有 4KB
  • 请求携带影响效率
  • 需要封装才能用

localStorage 和 sessionStorage

  • 容量5M
  • 不用在请求中携带
  • sessionStorage(浏览器关了会清掉)

相关文章

  • Front Interview导航2020-09-07

    JavaScript 【面试】前端JavaScript面试技巧【反向面试】—反问面试官的问题玩转经典十大Top10...

  • 前端JavaScript面试技巧

    导读 请搭配导图一起看 基层攻城狮 基础知识 高级攻城狮 项目经验 架构师 解决方案https://zhuanla...

  • 前端JavaScript面试技巧

    1-1 课程概述 要做什么?——讲解前端 JS 基础面试题 哪些部分?——JS 基础,JS-WEB-API,JS ...

  • 前端JavaScript面试技巧

    第5章 JS-Web-API(上) 从基础知识到JSWebAPI 下面来进行一个抛砖引玉回顾JS基础知识1.变量类...

  • 前端JavaScript面试技巧

    先看几道面试题: 1、JS中使用typeof能得到哪些类型。//JS变量类型2、何时使用“==”、“===”。//...

  • 前端JavaScript面试技巧

    加vx:dailaoer-com 9.9¥全 这是一门让你在前端面试脱颖而出的课程,BAT高级前端工程师亲授,以搞...

  • 前端随笔-面试

    阿里巴巴前端面试经历 JavaScript权威面试指南

  • 前端面试的经典题

    前端面试的经典题 前端面试三部曲 前端面试概念收集器 前端面试的经典题 前端面试的难题和怪题 Javascript...

  • 前端JavaScript高级面试技巧[1]

    第1章 课程介绍 1-1 导学 课程概述 做什么?— 讲解前端 JS 高级面试题 哪些部分?— 高级基础, 框架原...

  • 前端JavaScript高级面试技巧[2]

    第5章 虚拟 DOM vdom 是 vue 和 React 的核心 vdom 比较独立,使用也比较简单 vdom ...

网友评论

      本文标题:前端JavaScript面试技巧

      本文链接:https://www.haomeiwen.com/subject/kmesgctx.html