面试回顾(一)

面试回顾

1.基本数据类型

答:基本数据类型有string,null,number,symbol,undefined,boolean。

2.string和object的区别

答:string是基本数据类型,object是引用数据类型。基本数据类型是储存于栈中,引用数据类型存储于堆中。

string用于表示0或者多个16位unicode字符组成的字符序列。对象就是一组数据和功能的集合。

3.function和箭头函数的区别

  • 写法不一样
function test(a,b){
	return a-b;
}
var test2 = (a,b)=>{
	return a-b;
}
  • this指向不一样
// function的this指向在调用的时候才知道指向谁,是不固定的
function test(){
	console.log(this);
}
test();	//Window {postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window, …}
var obj = {aa:test};
obj.aa(); //{aa: ?}

// 箭头函数没有自己的this,它里面的this是继承所属上下文中的this,所以this指向是固定的
var test1 = () =>{
	console.log(this);
}
test1(); //Window {postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window, …}
var obj1 = {bb:test1};
obj1.bb(); //Window {postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window, …}
  • function可以作为构造函数,但是箭头函数不行
function test(){
	console.log(‘1‘);
}
let t = new test();  //1
//箭头函数没有prototype,constructor在prototype中,所以不能使用new生成构造函数
var test1 = ()=>{
	console.log(‘2‘);
}
let t1 = new test1();  //test1 is not a constructor
  • function可以先调用再定义,箭头函数不行
test(); //1
function test(){
	console.log(‘1‘);
}
test1(); //Uncaught TypeError: test1 is not a function
//用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!
function test1(){
	console.log(‘2‘);
}

4.箭头函数为什么不能使用new

new一个实例的过程

function New(fc){
    //1.创建一个新的对象
    let newObj = {};
    //2.将对象的_proto_指向函数的prototype
    if(fc.prototype!==null){
        newObj.__proto__=fc.prototype;
    }
    //3.调用apply或者call方法,将步骤1新创建的对象作为this的上下文
    let res = fc.apply(newObj,Array.prototype.slice.call(arguments,1));
    if((typeof res === ‘object‘|| typeof res === ‘function‘) && res!==null){
        return res;
    }
    //4.如果该函数没有返回对象,则返回this
    return newObj;
}
function A(){
    return 1;
}
var B = () => {
    return 1;
}
console.log(New(A))
console.log(New(B))	// 箭头函数没有自己的原型prototype,没有this指向

5.callback

回调函数,把函数作为参数传给另一个函数进行调用,一般来说,只要参数是一个函数,那么这个函数就是回调。

  • 异步调用(例如读取文件,进行HTTP请求,动态加载js文件,图片加载完成后进行回调)
  • 事件监听器、处理器
$button.on(‘click‘, function(){})
  • setTimeout、setInterval方法

6.call和apply

call和apply 都是用来修改函数中this的指向问题

不同的是传参方式,call方法可以传多个参数,apply方法只能将多个参数合成一个数组作为参数

var name = ‘windowName‘
var age = ‘windowAge‘
var person = {
    name : ‘personName‘,
    age : ‘personAge‘,
    getPerson : function(){
        return this.name + ‘ ‘ + this.age;
    },
    setPerson : function(name, age){
        return name + ‘ ‘ + age;
    }
}
var person1 = {
    name : ‘person1Name‘
}
console.log(person.getPerson());	//personName personAge
// 使用call和apply,不传任何参数,默认指向windows
console.log(person.getPerson.call())//windowName windowAge
console.log(person.getPerson.apply())//windowName windowAge
// 有参数时,this指向第一个参数
console.log(person.getPerson.call(person))//personName personAge
console.log(person.getPerson.apply(person1))//person1Name undefined 
// 当需要传递参数时,call可以直接写多个参数,apply需要用数组方式传递
console.log(person.setPerson.call(person,‘callName‘,‘callAge‘)) //callName callAge
console.log(person.setPerson.apply(person1,[‘applyName‘,‘applyAge‘])) //applyName applyAge
//当参数超过3个时,call会比apply性能好
//call 方法比 apply 快的原因是方法的参数格式正是内部方法所需要的格式。

7.前端的性能优化

  • 减少网络连接

    • 合并文件
    • 对图片进行处理(雪碧图-将多个图片合成一张图片;Base64-将图片的内容以base64的形式嵌在HTML中;使用icon小图标)
    • 减少重定向(当不得不重定向,使用301永久重定向,减少请求次数)
    • 使用缓存(使用cath-control或者expired这类强缓存,缓存不过期的情况下,直接从缓存中读取;当缓存过期,可以使用etag或者last-modified这类协商缓存,向服务器发送请求,如果资源没变化,直接从缓存读取,返回304;如果资源更新了,服务器将更新之后的内容发给浏览器,返回200
    • 避免使用空的src或者href(链接空的href会导致重定向到当前页面)
  • 减小资源大小

    • 压缩(对HTML,CSS,JS,图片等进行压缩
    • 使用gzip进行压缩
  • 优化网络连接

    • 使用DNS预解析(提前解析域名,将结果缓存在系统缓存中,减少解析域名的时间)
      • <link rel=‘dns-prefetch‘ href=‘www.baidu.com‘>
    • 持久连接(使用connect:keep-alive进行持久连接)
  • 优化资源加载

    • 资源加载的位置(css文件放在head中,先外链,后内部;js文件放在body下,先外链,后内部;避免在body中使用style和script)
    • 资源加载的时机(异步script标签-async,资源懒加载和预加载,模块按需加载)
      • 懒加载:可视区加载,条件加载,纯粹延时加载
      • 预加载:preload 加载页面必需的资源,prefetch 预测加载下一屏数据
  • 减少重绘回流

    • 样式设置(避免使用很多层的选择器,减少使用table布局;避免使用CSS表达式;尽量给图片、元素设置宽高;使用css实现效果而不使用js)

    • DOM优化

      • 缓存DOM节点

        • let div = document.getElementById(‘app‘)
      • 减少DOM的深度和数量

      • 批量操作DOM或者CSS样式

      • 防抖(debounce)和节流(throttle)

        • function debounce(fc,wait){
          	let timer;
          	return function(){
          		var self = this;
          		if(timer!==null)
          			clearTimeout(timer);
          		timer = setTimeout(function(){
          			fc.apply(self);
          		},wait)
          	}
          }
          
        • function throttle(fc,wait){
              let canRun = true;
              return function(){
                  if(canRun){
                      canRun = false;
                      fc.apply(this,arguments);
                      serTimeout(function(){
                          canRun = true;
                      },wait)
                  }  
              }
          }
          
  • 使用较好的API

    • 选择对的选择器(id > 类/属性/伪类 > 标签/为元素)
      • id选择器(#app)
      • 类选择器(.content)
      • 标签选择器(div,p)
      • 相邻选择器(div+p)
      • 子类选择器(ul > li)
      • 后代选择器(li a)
      • 通配选择器(*)
      • 属性选择器(a[rel="external"])
      • 伪类选择器(a:hover,li:nth-child)
      • 伪元素选择器(div::before,li:first-letter)
    • 使用web worker(Web Worker是HTML5提供的一个javascript多线程解决方案)
  • webpack优化

    • 打包公共组件
    • 动态加载和按需导入

8.输入域名这个过程会发生什么

  • DNS解析
  • TCP连接
  • 发送http请求
  • 服务器收到请求回应http报文
  • 浏览器渲染http
  • 关闭TCP连接

面试回顾(一)

上一篇:序列化Gadget学习篇二 CommonCollections1


下一篇:Git简介