前端基本面试题

1.this指向问题

1.在普通函数中,this指向window

2.构造函数中this指向它的实例

3.普通函数this谁调用就指向谁

4.箭头函数中this指向父级上下文

5.Function.prototype.call 或 Function.prototype.apply 调用跟普通的函数调用相比,用 Function.prototype.call 或 Function.prototype.apply 可以动态地
改变传入函数的 this:

 

 

2.

Java一对一答疑,帮助有志青年!使用QQ在线辅导,哪里不懂问哪里,整个过程都是一对一,学习更有针对性。和作者直接交流,不但提升技能,还提升 Level;当你决定加入我们,你已然超越了 90% 的程序员。猛击这里了解详情。

面向对象简称 OO(Object Oriented),20 世纪 80 年代以后,有了面向对象分析(OOA)、 面向对象设计(OOD)、面向对象程序设计(OOP)等新的系统开发方式模型的研究。

对 Java 语言来说,一切皆是对象。把现实世界中的对象抽象地体现在编程世界中,一个对象代表了某个具体的操作。一个个对象最终组成了完整的程序设计,这些对象可以是独立存在的,也可以是从别的对象继承过来的。对象之间通过相互作用传递信息,实现程序开发。

对象的概念

Java 是面向对象的编程语言,对象就是面向对象程序设计的核心。所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。对象有以下特点:

  • 对象具有属性和行为。
  • 对象具有变化的状态。
  • 对象具有唯一性。
  • 对象都是某个类别的实例。
  •  一切皆为对象,真实世界中的所有事物都可以视为对象。


例如,在真实世界的学校里,会有学生和老师等实体,学生有学号、姓名、所在班级等属性(数据),学生还有学习、提问、吃饭和走路等操作。学生只是抽象的描述,这个抽象的描述称为“类”。在学校里活动的是学生个体,即张同学、李同学等,这些具体的个体称为“对象”,“对象”也称为“实例”。

2.面向对象的三大核心特性

##### 面向对象(OOP)。 

js是一门面向对象的语言,面向对象是一种给编程思想(万物皆对象)与之对应的是面向过程(类) 

js本身就是基于面向对象构建出来的(例如:JS中有很多内置类,Array ,Object ,Function,String像promise就是ES6中新增的一个内置类,我们可以基于new Promise来创建一个实例,管异步编程)

一般我们平时用的Vue/REACT/JQUER也都是基于面向对象构建出来的,他们都是类,平时开发的时候都是创建他们的实例来操作   

我在自己真实项目中,也封过一些组件插件指令(面向对象,插件       :NODE路由,sw),他们都是基于面向对象开发的,这样可以创造不同的实例,来管理私有属性和公有的方法。

***面向对象(OOP)类***

1.类  封装  继承  多态

   封装:低耦合,高内聚

   多态:重载和重写

重载:js中是没有重载概念的(后端:方法名相同,但是形参个数不同或者类型不一样,或者类型不一样,或者返回值不同(类型),根据传参的不同,实现不同的效果)

重写:在类的继承中,子类可以重写父类的方法 

3.事件模型:事件委托、代理?如何让事件先冒泡后捕获?

事件冒泡/捕获

事件冒泡事件捕获
IE和标准浏览器标准浏览器
传播顺序:先捕获,后冒泡
早期IE只支持事件冒泡,不支持事件捕获

 

绑定事件

.addEventListener('click',function(){},false).attachEvent('onclick',function(){})
标准浏览器IE
三个参数:
1.事件类型,没有on
2.事件处理函数
3.布尔型的数值,默认false(事件冒泡),true(事件捕获)
有两个参数:
1.事件类型,有on
2.事件处理函数
阻止事件冒泡/捕获 : e.stopPropagation();阻止事件冒泡 : window.event,cancelBubble=true
 问题:
1.顺序相反
2.this指向window

事件冒泡优点

1.有很多子元素,并且绑定同一种事件,可以委托给父元素代理(事件代理/事件委托)

<body>
<ul id="ul1">
    <li>001</li>
    <li>002</li>
    <li>003</li>
    <li>004</li>
    <li>005</li>
</ul>

<script>
    var oUl = document.getElementById('ul1');
    oUl.onclick = function(e){
        //获取事件源
        var target=e?target = e.target:window.event.srcElement;
        console.log(target.innerHTML);
    };

</script>
</body>

2.对于后生成事件的绑定,可以用事件委托

<body>
    <button id="btn">增加</button>
    <ul id="ul1">
        <li>001</li>
        <li>002</li>
        <li>003</li>
        <li>004</li>
        <li>005</li>
    </ul>

    <script>
        var oUl = document.getElementById('ul1');
        var aLi = oUl.getElementsByTagName('li');
        var oBtn = document.getElementById('btn');
        oUl.onclick = function (e) {
            console.log(e.currentTarget);//this
            console.log(e.target);//事件源
            };

        oBtn.onclick = function () {
            var oLi = document.createElement('li');
            oLi.innerHTML = Math.random();
            oUl.appendChild(oLi);
        };

    </script>
</body>
            
e.currentTarget=this  
e.target获取事件源  
可以通过e.currentTarget和e.target的比较得知是不是由事件冒泡触发的

总结:事件模型/事件冒泡/事件委托:利用事件冒泡,把子元素委托给父元素绑定

4.window的onload事件和domcontentloaded

window.onload:

当一个资源及其依赖资源已完成加载时,将触发onload事件。

 

document.onDOMContentLoaded:

当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,而无需等待样式表、图像和子框架的完成加载。

 

区别:

①onload事件是DOM事件,onDOMContentLoaded是HTML5事件。

②onload事件会被样式表、图像和子框架阻塞,而onDOMContentLoaded不会。

③当加载的脚本内容并不包含立即执行DOM操作时,使用onDOMContentLoaded事件是个更好的选择,会比onload事件执行时间更早。

 5.for···in和for···of的区别:(for···in取key,for··of取value)

①从遍历数组角度来说,for···in遍历出来的是key(即下标),for···of遍历出来的是value(即数组的值);

 

var arr = [99,88,66,77];

for(let i in arr){

    console.log(i);   //0,1,2,3

}

for(let i of arr){

    consoel.log(i);   //99,88,66,77

}

 

②从遍历字符串的角度来说,同数组一样。

 

③从遍历对象的角度来说,for···in会遍历出来的为对象的key,但for···of会直接报错。

 

var obj = {name:"Bob",age:25};

for(var i in obj){

console.log(i)  // name age

}

for(var i of obj){

console.log(i)   //报错

}

6.iframe的优缺点有哪些?

优点:

①iframe能够原封不动的把嵌入的网页展现出来;

②如果有多个网页引用iframe,那么你只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷。

③网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,可以增加代码的可重用。

④如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决。

 

缺点:

①会产生很多页面不易管理;

②iframe框架结构有时会让人感到迷惑,如果框架个数多的话,可能会出现上下、左右滚动条,会分散访问者的注意力,用户体验度差。

③代码复杂,无法被一些搜索引擎索引到,这一点很关键,现在的搜索引擎爬虫还不能很好的处理iframe中的内容,所以使用iframe会不利于搜索引擎优化。

④很多的移动设备(PDA 手机)无法完全显示框架,设备兼容性差。

⑤iframe框架页面会增加服务器的http请求,对于大型网站是不可取的。

 

 

本题延申:

frame框架:

优点:

①重载页面时不需要重载整个页面,只需要重载页面中的一个框架页(减少了数据的传输,加快了网页下载速度);

②技术易于掌握,使用方便,使用者众多,可主要应用于不需搜索引擎来搜索的页面;

③方便制作导航栏 ;

 

缺点:

①搜索引擎程序不能解读这种页面;

②不能打印全框架;

③浏览器的后退按钮无效;

④手机等终端设备无法显示全部框架内容;

 

iframe和frame区别:

①frame不能脱离frameSet单独使用,iframe可以;

②frame不能放在body中,否则不能正常显示,frame不能和body同时使用,iframe可以;

③嵌套在frameSet中的iframe必需放在body中,不嵌套在frameSet中的iframe可以随意使用;

④frame的高度只能通过frameSet控制;iframe可以自己控制,不能通过frameSet控制;

⑤iframe 可以放到表格里面。frame 则不行。 

7.js数组去重

 ES6-set
使用ES6中的set是最简单的去重方法

var arr  = [1,1,'true','true',true,true,15,15,false,false, undefined,
undefined, null,null, NaN,NaN,'NaN', 0, 0, 'a', 'a',{},{}];
 
function arr_unique1(arr){
return  [...new Set(arr)];
//或者
//return  Array.from(new Set(arr));
}
arr_unique1(arr); // (13)[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

利用Map数据结构去重
创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。

function arr_unique2(arr) {
  let map = new Map();
  let array = new Array();  // 数组用于返回结果
  for (let i = 0; i < arr.length; i++) {
    if(map .has(arr[i])) {  // 如果有该key值
      map .set(arr[i], true);
    } else {
      map .set(arr[i], false);   // 如果没有该key值
      array .push(arr[i]);
    }
  }
  return array ;
}

 console.log(arr_unique2(arr)); //(13) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN"

利用递归去重

function arr_unique3(arr) {
     var array= arr;
     var len = array.length;
     array.sort(function(a,b){   //排序后更加方便去重
     return a - b;
    })
    
 function loop(index){
        if(index >= 1){
            if(array[index] === array[index-1]){
                array.splice(index,1);
            }
            loop(index - 1);    //递归loop,然后数组去重
        }
    }
    loop(len-1);
    return array;
}
 
console.log(arr_unique3(arr)); //(14) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

.......

8.什么是数组扁平化?

数组扁平化就是将一个多维数组转换为一个一维数组

实现基本方式

1、对数组的每一项进行遍历。

2、判断该项是否是数组。

3、如果该项不是数组则将其直接放进新数组。

4、是数组则回到1,继续迭代。

5、当数组遍历完成,返回这个新数组

function flatten(arr){
	var box = [];
	arr.map(v => {
		if(Array.isArray(v)){
			box = box.concat(flatten(v))
		}else{
			box.push(v);
		}
	})
	return box;
}
console.log(flatten(arr)); 

第二种(不推荐):
function flatten(arr){
	return arr.toString().split(",").map(v => {
		return Number(v);
	})
}
console.log(flatten(arr)); 

第三种:
function flatten(arr){
	console.log(arr.join(","))
	return arr.join(",").split(",").map(v => {
		return parseInt(v);
	})
}
console.log(flatten(arr)); 

第四种:
var arr = [1,2,[3,4,[5,6,[7,8,[9,10]]]]];
function flatten(arr){
	return arr.reduce((result,item) => {
		console.log(result,item)
		return result.concat(Array.isArray(item) ? flatten(item) : item);
	},[]);
}
console.log(flatten(arr)); 

第五种:
console.log([].concat(...arr));
function flatten(arr){
	while(arr.some(item => Array.isArray(item))){
		arr = [].concat(...arr);
	}
	return arr;
}
console.log(flatten(arr));    

9.垃圾回收机制

垃圾回收机制
浏览器的 Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。其原理是:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大并且GC时停止响应其他操作,所以垃圾回收器会按照固定的时间间隔周期性的执行
 

10。什么是函数柯里化

百度百科:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。通俗点说就是将一个函数拆分成多个函数,是固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。来个简单的例子

// 实现一个简单的加法
function add(a,b){return a+b}
add(1,2);
// 用柯里化实现
const currying = (x) => {
     return (y) => {return x+y}
}
console.log(currying(1)(2)) // 3

这里就是使用柯里化把add函数拆分成了两个函数,currying首次执行返回一个新的函数,然后再次调用返回结构,返回一个函数的特征就是上一章所说到的高阶函数,柯里化函数就是高阶函数的一种。这里就会有人提问了,为什么要那么费劲实现add函数?有道经典的面试题实现add(1)(2)(3)(4)=10;

// 我们可以这样理解调用add(1)时返回一个函数fn,然后执行fn(2)依次被调用,当执行到最后一次返回结果
function add(num){
    var sum=num;
    var fn=function(v){
        sum+=v;
        return fn
    }; 
    fn.toString=function(){
        return sum
    };
    return fn
}
console.log(add(1)(2)(3)(4)) // 10
// 执行add(1)时返回了fn函数给2,3,4执行,同时定义了fn的toString方法,
// 每个对象的toString和valueOf方法都可以被改写,每个对象执行完毕,如果被用以操作JavaScript解析器就会自动调用对象的toString或者valueOf方法
// 利用toString隐式调用的特性,当最后执行时隐式调用,并计算最终的值返回

面试题的内容还有 add(1)(1,2,3)(2)=9 这样的形式,我们上面的方法就没办法执行出正确的答案了,下面来优化一下

function add(){
    var args = [...arguments];
    var fn=function(){
        args.push(...arguments);
        return fn
    }; 
    fn.toString=function(){
        return _args.reduce(function (a, b) {
            return a + b;
        });
    };
    return fn
}
consolo.log(add(1)(1,2,3)(2)) // 9

以上就是函数柯里化的简单实现。继续来实现一些例子来看看柯里化的好处

// 实现一个判断数据类型的方法
const checktype = function(type, content) {
    return Object.prototype.toString.call(content) === `[object ${type}]`;
}
checktype('Number',2); // true
// 这种方法总是要把type参数传过去,如果写错了就会影响到正确的结果了,可以考虑下如何做到把“Number“做到复用

const curry = function(type){
    return function(content){
        return Object.prototype.toString.call(content) === `[object ${type}]`;
    }
}
const isNumber =  curry('Number');
isNumber(3) // true 
// 这里就实现参数的复用了,这样的实现给之后的调用带来了很大的便利

函数柯里化是可以给我们带来一下便捷,但是也是会有缺点的,在性能上也会受到影响,比如add函数里面需要创建数组去存放每次调用的时候的参数,创建闭包函数这些都会对内存跟速度上会带来花销,存取arguments对象通常要比存取命名参数要慢一点。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端基础面试题2021 pdf》是一份前端开发面试题目集合的PDF文件。这份题目集合包含了2021年前端开发领域的基础知识和技能要求。 这份PDF文件主要包括了以下内容:HTML、CSS、JavaScript基础知识、网络与安全、框架与工具、性能优化与调试、前端工程化等方面的题目。 在HTML方面,题目涉及HTML标签、常见元素的使用、语义化等内容。在CSS方面,题目包括选择器、盒模型、浮动、定位、布局等知识。在JavaScript方面,题目涉及变量、数据类型、运算符、函数、作用域、闭包、面向对象等内容。 此外,网络与安全的题目涵盖了HTTP协议、HTTPS、跨域、攻击与防御等知识。框架与工具方面,题目包括对常见框架如React、Vue的理解、webpack等工具的使用。性能优化与调试的题目涉及浏览器渲染原理、代码优化、性能测试等。而前端工程化方面的题目则包括项目构建、版本控制、代码规范等方面。 通过研究这份面试题目集合,考生可以了解2021年前端开发领域的基本要求和技能点,提前进行准备和复习。同时,这份题目集合也可以帮助面试官评估候选人的技术水平和能力,从而做出合理的招聘决策。 总的来说,《前端基础面试题2021 pdf》是一份在前端开发领域进行面试准备和评估的有用资源。如果你是一位前端开发者,阅读并解答其中的题目,有助于加深对前端知识和技能的理解和掌握。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值