面试题-JavaScript

文章目录

      • 1-get 请求传参长度的误区
      • 2-get 和 post 请求在缓存方面的区别
      • 3-说一下闭包
      • 4-说一下类的创建和继承
      • 5-如何解决异步回调地狱
      • 6-说说前端中的事件流
      • 7-如何让事件先冒泡后捕获
      • 8-说一下事件委托
      • 9-说一下图片的懒加载和预加载
      • 10-mouseover 和 mouseenter 的区别
      • 11-JS 的 new 操作符做了哪些事情
      • 12-改变函数内部 this 指针的指向函数(bind,apply,call 的区别)
      • 13-JS 的各种位置,比如 clientHeight,scrollHeight,offsetHeight ,以及 scrollTop, offsetTop,clientTop 的区别?
      • 14-JS 拖拽功能的实现
      • 15-异步加载 JS 的方法
      • 16-Ajax 解决浏览器缓存问题
      • 17-JS 的节流和防抖
      • 18-JS 中的垃圾回收机制
      • 19-eval 是做什么的
      • 20-如何理解前端模块化
      • 21-说一下 CommonJS、AMD 和 CMD
      • 22-对象深度克隆的简单实现
      • 23-实现一个 once 函数,传入函数参数只执行一次
      • 24-将原生的 ajax 封装成 promise
      • 25-JS 监听对象属性的改变
      • 26-如何实现一个私有变量,用 getName 方法可以访问,不能直接访问
      • 27-==和===、以及 Object.is 的区别
      • 28-setTimeout、setInterval 和 requestAnimationFrame 之间的区别
      • 29-实现一个两列等高布局,讲讲思路
      • 30-自己实现一个 bind 函数
      • 31-用 setTimeout 来实现 setInterval
      • 32-JS 怎么控制一次加载一张图片,加载完后再加载下一张
      • 33-代码的执行顺序
      • 34-如何实现 sleep 的效果(es5 或者 es6)
      • 35-简单的实现一个promise
      • 36-Function._proto_(getPrototypeOf)是什么?
      • 37-实现 JS 中所有对象的深度克隆(包装对象,Date 对象,正则对象)
      • 38-简单实现 Node 的 Events 模块
      • 39-箭头函数中 this 指向举例
      • 40-JS 判断类型
      • 41-数组常用方法
      • 42-数组去重
      • 43-闭包 有什么用
      • 44-事件代理在捕获阶段的实际应用
      • 45-去除字符串首尾空格
      • 46-性能优化
      • 47-能来讲讲 JS 的语言特性吗
      • 48-如何判断一个数组(讲到 typeof 差点掉坑里)
      • 49-你说到 typeof,能不能加一个限制条件达到判断条件
      • 50-JS 实现跨域
      • 51-JS 基本数据类型
      • 52-JS 深度拷贝一个元素的具体实现
      • 53-之前说了 ES6 set 可以数组去重,是否还有数组去重的方法
      • 54-重排和重绘,讲讲看
      • 55-JS 的全排列
      • 56-跨域的原理
      • 57-不同数据类型的值的比较,是怎么转换的,有什么规则
      • 58-null == undefined 为什么
      • 59-this 的指向 哪几种
      • 60-暂停死区
      • 61-AngularJS 双向绑定原理
      • 62-写一个深度拷贝
      • 63-简历中提到了 requestAnimationFrame,请问是怎么使用的
      • 64-有一个游戏叫做Flappy Bird,就是一只小鸟在飞,前面是无尽的沙漠,上下不断有钢管生成,你要躲避钢管。然后小明在玩这个游戏时候老是卡顿甚至崩溃,说出原因(3-5 个)以及解决办法(3-5 个)
      • 65-编写代码,满足以下条件:
      • 66-什么是按需加载
      • 67-说一下什么是 virtual dom
      • 68-webpack 用来干什么的
      • 69-ant-design 优点和缺点
      • 70-JS 中继承实现的几种方式,
      • 71-写一个函数,第一秒打印 1,第二秒打印 2
      • 72-Vue 的生命周期
      • 73-简单介绍一下 symbol
      • 74-什么是事件监听
      • 75-介绍一下 promise,及其底层如何实现
      • 76-说说 C++,Java,JavaScript 这三种语言的区别
      • 77-JS 原型链,原型链的顶端是什么?Object 的原型是什么?Object 的原型的原型是什么?在数组原型链上实现删除数组重复数据的方法
      • 78-什么是 js 的闭包?有什么作用,用闭包写个单例模式
      • 79-promise+Generator+Async 的使用
      • 80-事件委托以及冒泡原理。
      • 81-写个函数,可以转化下划线命名到驼峰命名
      • 82-深浅拷贝的区别和实现
      • 83-JS 中 string 的 startwith 和 indexof 两种方法的区别
      • 84-JS 字符串转数字的方法
      • 85-let const var 的区别 ,什么是块级作用域,如何用 ES5 的方法实现块级作用域(立即执行函数),ES6 呢
      • 86-ES6 箭头函数的特性!!!
      • 87-setTimeout 和 Promise 的执行顺序
      • 88-有了解过事件模型吗,DOM0 级和 DOM2 级有什么区别,DOM 的分级是什么
      • 89-平时是怎么调试JS 的
      • 90-JS 的基本数据类型有哪些,基本数据类型和引用数据类型的区别,NaN 是什么的缩写,JS 的作用域类型,undefined==null 返回的结果是什么, undefined 与 null 的区别在哪,写一个函数判断变量类型
      • 91-setTimeout(fn,100);100 毫秒是如何权衡的
      • 92-JS 的垃圾回收机制
      • 93-写一个 newBind 函数,完成 bind 的功能。
      • 94-怎么获得对象上的属性:比如说通过 Object.key()
      • 95-简单讲一讲 ES6 的一些新特性
      • 96-call 和 apply 是用来做什么?
      • 97-了解事件代理吗,这样做有什么好处
      • 98-如何写一个继承?
      • 99-给出以下代码,输出的结果是什么?原因?
      • 100-给两个构造函数A 和 B,如何实现 A 继承 B?
      • 101-问能不能正常打印索引
      • 102-如果已经有三个promise,A、B 和 C,想串行执行,该怎么写?
      • 103-知道 private 和 public 吗
      • 104-基础的 js
      • 105-async 和 await 具体该怎么用?
      • 106-知道哪些 ES6,ES7 的语法
      • 107-promise 和 await/async 的关系
      • 108-JS 的数据类型
      • 109-JS 加载过程阻塞,解决方法。
      • 110-JS 对象类型,基本对象类型以及引用对象类型的区别
      • 111-JavaScript 中的轮播实现原理?假如一个页面上有两个轮播,你会怎么实现?
      • 112-怎么实现一个计算一年中有多少周?
      • 113-面向对象的继承方式
      • 114-JS 的数据类型
      • 115-引用类型常见的对象
      • 116-es6 的常用
      • 117-class
      • 118-口述数组去重
      • 119-call 和 apply 的区别
      • 120-es6 的常用特性
      • 121-箭头函数和 function 有什么区别
      • 122-new 操作符原理
      • 123-bind,apply,call
      • 124-bind 和 apply 的区别
      • 125-闭包!!!
      • 126-promise 实现
      • 127-assign 的深拷贝
      • 128-说 promise,没有 promise 怎么办
      • 129-事件委托
      • 130-arguments
      • 131-箭头函数获取 arguments
      • 132-Promise
      • 133-事件代理
      • 134-Eventloop

1-get 请求传参长度的误区

误区:我们经常说get 请求参数的大小存在限制,而 post 请求的参数大小是无限制的。

实际上HTTP 协议从未规定 GET/POST 的请求长度限制是多少。

对 get 请求参数的限制是来源与浏览器或web 服务器,浏览器或web 服务器限制了url 的长度。为了明确这个概念,我们必须再次强调下面几点:

HTTP 协议 未规定 GET 和POST 的长度限制

GET 的最大长度显示是因为 浏览器和 web 服务器限制了 URI 的长度不同的浏览器和 WEB 服务器,限制的最大长度不一样

要支持IE,则最大长度为 2083byte,若只支持Chrome,则最大长度 8182byte

2-get 和 post 请求在缓存方面的区别

get 请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。

post 不同,post 做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。因此get 请求适合于请求缓存。

3-说一下闭包

一句话可以概括:闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用, 子函数所在的父函数的作用域不会被释放。

4-说一下类的创建和继承

1、类的创建(es5):new 一个function

在这个function 的prototype 里面增加属性和方法。

下面来创建一个 Animal 类:

// 定义一个动物类
function Animal (name) {
     
	// 属性
	this.name = name || 'Animal';
	// 实例方法
  this.sleep = function(){
     
		console.log(this.name + '正在睡觉!');
	}
}

// 原型方法
Animal.prototype.eat = function(food) {
      
  console.log(this.name + '正在吃:' + food);
};

这样就生成了一个Animal 类,实力化生成对象后,有方法和属性。

2、类的继承——原型链继承:原型链继承

function Cat(){

}
Cat.prototype = new Animal(); 
Cat.prototype.name = 'cat';

//	Test Code
var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.eat('fish')); 
console.log(cat.sleep());

console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

介绍:在这里我们可以看到 new 了一个空对象

这个空对象指向Animal 并且Cat.prototype 指向了这个空对象,这种就是基于原型链的继承。

特点:基于原型链,既是父类的实例,也是子类的实例缺点:无法实现多继承。

3、构造继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Cat(name){
      
  Animal.call(this); 
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.sleep());

console.log(cat instanceof Animal); // false 
console.log(cat instanceof Cat); // true

特点:可以实现多继承

缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法。

4、实例继承和拷贝继承

实例继承:为父类实例添加新特性,作为子类实例返回拷贝继承:拷贝父类元素上的属性和方法

上述两个实用性不强,不一一举例。

5、组合继承

相当于构造继承和原型链继承的组合体。

通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

function Cat(name){
     
	Animal.call(this); 
  this.name = name || 'Tom';
}

Cat.prototype = new Animal(); 
Cat.prototype.constructor = Cat;

// Test Code
var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.sleep());

console.log(cat instanceof Animal); // true 
console.log(cat instanceof Cat); // true

特点:可以继承实例属性/方法,也可以继承原型属性/方法

缺点:调用了两次父类构造函数,生成了两份实例

6、寄生组合继承

通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性

function Cat(name){
      
  Animal.call(this); 
  this.name = name || 'Tom';
}

(function(){
     
  // 创建一个没有实例方法的类
  var Super = function(){
     }; 
  Super.prototype = Animal.prototype;
  
  //将实例作为子类的原型
  Cat.prototype = new Super();
})();

// Test Code
var cat = new Cat(); 
console.log(cat.name); 
console.log(cat.sleep());

console.log(cat instanceof Animal); // true 
console.log(cat instanceof Cat); //true

较为推荐

5-如何解决异步回调地狱

promise、generator、async/await

6-说说前端中的事件流

HTML 中与javascript 交互是通过事件驱动来实现的,例如鼠标点击事件 onclick、页面的滚动事件onscroll 等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。

什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2 级事件流包括下面几个阶段。

事件捕获阶段处于目标阶段事件冒泡阶段

addEventListener:addEventListener 是DOM2 级事件新增的指定事件处理程序的操作

这个方法接收 3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true

表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

IE 只支持事件冒泡。

7-如何让事件先冒泡后捕获

在DOM 标准事件模型中,是先捕获后冒泡

但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数

监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获之间。

8-说一下事件委托

简介:事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素 DOM 的类型,来做出不同的响应。

举例:最经典的就是ul 和li 标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在 li 标签上直接添加,而是在ul 父元素上添加。

好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。

9-说一下图片的懒加载和预加载

预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。

懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。

两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。

懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

10-mouseover 和 mouseenter 的区别

mouseover:当鼠标移入元素或其子元素都会触发事件,所以有一个重复触发,冒泡的过程。

对应的移除事件是 mouseout

mouseenter:当鼠标移除元素本身(不包含元素的子元素)会触发事件,也就是不会冒泡。

对应的移除事件是 mouseleave

11-JS 的 new 操作符做了哪些事情

new 操作符新建了一个空对象,这个对象原型指向构造函数的 prototype,执行构造函数后返回这个对象。

12-改变函数内部 this 指针的指向函数(bind,apply,call 的区别)

通过apply 和call 改变函数的this 指向

他们两个函数的第一个参数都是一样的表示要改变指向的那个对象

第二个参数,apply 是数组,而call 则是arg1,arg2…这种形式。

通过bind 改变this 作用域会返回一个新的函数,这个函数不会马上执行。

13-JS 的各种位置,比如 clientHeight,scrollHeight,offsetHeight ,以及 scrollTop, offsetTop,clientTop 的区别?

clientHeight:表示的是可视区域的高度,不包含border 和滚动条

offsetHeight:表示可视区域的高度,包含了border 和滚动条

scrollHeight:表示了所有区域的高度,包含了因为滚动被隐藏的部分。

clientTop:表示边框border 的厚度,在未指定的情况下一般为 0

scrollTop:滚动后被隐藏的高度,获取对象相对于由offsetParent 属性指定的父坐标(css 定位的元素或body 元素)距离顶端的高度。

14-JS 拖拽功能的实现

首先是三个事件,分别是 mousedown,mousemove,mouseup

当鼠标点击按下的时候,需要一个 tag 标识此时已经按下,可以执行mousemove 里面的具体方法。

clientX,clientY 标识的是鼠标的坐标,分别标识横坐标和纵坐标,并且我们用 offsetX 和offsetY 来表示元素的元素的初始坐标,移动的举例应该是:

鼠标移动时候的坐标-鼠标按下去时候的坐标。也就是说定位信息为:
鼠标移动时候的坐标-鼠标按下去时候的坐标+元素初始情况下的offetLeft.

还有一点也是原理性的东西,也就是拖拽的同时是绝对定位,我们改变的是绝对定位条件下的left,以及top 等等值。

补充:也可以通过html5 的拖放(Drag 和 drop)来实现

15-异步加载 JS 的方法

defer:只支持IE 如果您的脚本不会改变文档的内容,可将 defer 属性加入到

你可能感兴趣的:(面试,面试,程序人生,经验分享)