前端面试(个人收藏总结)javascript篇(一)

5,751 阅读4分钟

前端面试(个人收藏总结)HTML篇

前端面试(个人收藏总结)CSS篇

前端面试(个人收藏总结)javascript篇(二)

JS中有多少种基本数据类型

undefined, null, boolean, string, number

Ps:ES6中新增symbol类型

参考:JavaScript的数据类型及其检测

JS变量按照存储方式区分为那些类型,并描述其特点

  • 值类型

  • 引用类型

参考:低门槛彻底理解JavaScript中的深拷贝和浅拷贝

JS中使用typeof能得到哪些类型

undefind、string、number、boolean、function、object

特别说明的是对象、数组、null都是object(函数虽是引用类型,但能识别),因为typeof没法区分引用类型

Ps:可以得到ES6中新增的symbol类型

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

可以用instanceof关键字

举个栗子:

var arr = []
arr instanceof Array //true
Array.isArray(arr) //true

何时使用'==='何时使用'=='

  • 双等会自动强制转换,有风险。

  • jQuery源码中推荐使用三等,我个人也是这么写的。双等可用于判断布尔值

参考:彻底终结 Javascript 背后的隐式类型转换

写一个继承的例子

//构造函数方式
function Animal { this.name = 'pig' }
function Animal2 { Animal.call(this); this.age = 18 }
console.log(new Animal2())
//缺点:无法继承Animal的原型对象

//原型链方式
function Animal { this.name = 'pig' }
function Animal2 { this.age = 18 }
Animal2.prototype = new Animal();
console.log(new Animal2())
//缺点:实际上是共享,修改原型对象里的内容,其它继承的类也会同步修改

//组合方式
function Animal { this.name = 'pig' }
function Animal2 { Animal.call(this); this.age = 18 }
Animal2.prototype = Animal.prototype;
console.log(new Animal2())
//缺点:由于引用同一个原型对象,无法区分对象是由谁实例化的

//最终方式
function Animal { this.name = 'pig' }
function Animal2 { Animal.call(this); this.age = 18 }
Animal2.prototype = Obiect.create(Animal.prototype);
Animal2.prototype.constructor = Animal2;
console.log(new Animal2())
//解释:通过创建新的对象,不再是同一个,再指定构造函数属性为自己

创建对象的几种方式

  • 字面量

  • object对象

  • 构造函数

  • object create

描述new一个对象的过程

  • 创建空对象,并继承原型对象

  • 执行构造函数,this指向这个空对象

  • 如果返回值是object则返回新对象,否则返回object

你对变量提升的理解

在执行代码时,变量和函数的声明会被提升到作用域的顶部(此时变量的值为undefined)

如果是全局,会被提升到脚本的最前面

如果是函数内,会被提升到函数内最前面,this也是

PS:注意函数表达式(匿名函数)的情况

PS2:注意ES6中let的情况,不会变量提升

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

  • 作为构造函数执行

  • 作为对象属性执行

  • 作为普通函数执行

  • call apply bind

创建10个a标签,点击弹出对应序号

for(var i=0;i<10;i++){
  (function(i){
  	var a = document.createElement('a');
    a.innerHtml=i+'<br>';
    a.onclick=function(e){
  		e.preventDefault();
      	alert(i)
	}
    document.body.appendChild(a)
  })(i)
}

如何理解作用域

只有函数作用域和全局作用域,ES6中新增块级作用域那是后话

函数外声明的变量为全局作用域,函数内可以使用

函数内声明的变量为函数作用域,函数外不可以使用

作用域链:一个自由变量一直往上寻找(定义时的)父级作用域内的变量的过程。

自由变量:当前作用域没有定义的变量

ps:花括号内使用let声明变量为块级作用域,只能内部使用,减少全局污染

了解闭包吗?

闭包:用一个函数去访问另一个函数内的内部变量的方式的特殊函数

使用场景:柯里化函数

参考:mp.weixin.qq.com/s/G9HIJWH-5…

同步和异步的区别?

同步会阻塞代码执行,异步不会

前端使用异步的场景?

  • 定时任务:setTimeout setInverval

  • 网络请求:ajax请求,动态加载

  • 事件绑定

JS运行机制简单说明

  • 单线程:JS引擎、事件触发器、定时触发器都是单线程的。
  • 任务队列:JS分为同步任务和异步任务,一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
  • event loop(事件循环机)制:执行栈中的代码调用某些api时,会在事件队列中添加各种事件,当栈中的代码执行完毕后,会读取事件队列中的事件并执行回调的循环过程。

参考:www.dailichun.com/2018/01/21/…

进程和线程

  • 进程:正在运行的应用程序,是应用程序的一个运行环境,是cpu资源分配的最小单位
  • 线程:建立在进程的基础上,用于执行操作(如执行代码),是cpu调度的最小单位,一个进程可以有多个线程

获取随机数,要求是长度一致的字符串格式

var random = Math.random();
var random = random+'00000000';
var random = random.slice(0,10);

写一个能遍历对象和数组的通用forEach函数

function foreach(obj,fn){
  var key;
  if(obj instanceof Array){
  	obj.forEach(function(item,index){
  		fn(index,item)
	})
  }else{
  	for(key in obj){
  		fn(key,obj[key])
	}
  }
}

JavaScript 中如何获取当前的时间戳

  • Date.now()

  • new Date().getTime()

  • +new Date()