前端面试题整理

前端面试题整理

1、请将一个URL的search部分参数与值转换成一个json对象?

function getJson(url){
	if(url === undefined || typeof url !== 'string') {
		return null
	}

	var items = url.split('?')[1].split('&');
	var json = {};

	for(var i = 0; i<items.length; i++){
		var item = items[i].split('=');
		json[item[0]] = item[1];
	}

	return json;
}

console.log(getJson('http://item.taobao.com.htm?a=1&b=2&d=xxx&e'))

2、数组去重的方法

es6:

function clearRepeat(arr){
var at = new Set(arr);
	return Array.from(at);
}

from()方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。如果对象是数组返回 true,否则返回 false。

es5数组去重的方法:

function unqiue(arr){
	for(var i = 0; i<arr.length; i++){
		for(var j= i+1; j<arr.length; j++){
			if(arr[i] === arr[j]){
				arr.splice(j,1)
				j--;
			}
		}
	}
	return arr
}

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。

注释:该方法会改变原始数组。
arrayObject.splice(index,howmany,item1,…,itemX)
参数 描述
index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
item1, …, itemX 可选。向数组添加的新项目。

3、连字符转驼峰形式

function toUpcase(str){
	var arr = str.split('-');
	var newArr = [];

	for(var i= 1; i<arr.length; i++){
		newArr[0] = arr[0];
		newArr.push(arr[i].charAt(0).toUpperCase() + arr[i].slice(1)); 
		var newArr1 = newArr.join('')
		
	}

	return newArr1;
}

slice() 方法可从已有的数组中返回选定的元素。

语法
arrayObject.slice(start,end)
参数 描述
start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
返回值
返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。

说明
请注意,该方法并不会修改数组,而是返回一个子数组。如果想删除数组中的一段元素,应该使用方法 Array.splice()。

4、字符串翻转

function reverse(str){
	var arr = str.split('');
	arr.reverse();
	var str1 = arr.join('')

	return str1;
}

console.log(reverse('1234567'))

5、作用域考题:分别输出1、2、3



for (var i = 1; i<= 3; i++) {
	(function (i){
		setTimeout(function(){
		console.log(i);
		},1000)
	})(i);
}

6、js实现随机取10-100之间的10个数字,存入一个数组,并排序

var arr = [];
function getRandom(num1,num2){
	var transition = num2 - num1 + 1;
	var res = Math.floor(Math.random() * transition + num1);
	return res;
}

for(var i = 0; i<10; i++){
	arr.push(getRandom(10,100))
}

arr.sort(function(a,b){
	return b-a;
})


console.log(arr);


7、连接两个数组

var arr1 = [1,2,3];
var arr2 = [4,5,6];

arr1 = arr1.concat(arr2);

console.log(arr1)

8、继承的例子

原型链继承

function Father(name){
	this.name = name;
	this.say = function (){
		console.log('我的名字是' + this.name)
	}
}

function Son(name){
	this.name = name;
}

var f= new Father('lisi');
Son.prototype = f;
var s = new Son('zhangsan');

console.log(s.name);
s.say1();

缺点:

引用类型的属性被所有实例共享
在创建Son 的实例时, 不能向Father传参

借用构造函数(经典继承)

function Parent(name,age){
	this.name = name;
	this.age = age;
	this.list = [1,2,3]
}
Parent.prototype.say = function(){
	console.log('hello')
}


function Child(sex,name){
	this.sex = sex;
	Parent.call(this,name);
}

var kid = new Child('man','lihong');
var kid2 = new Child('woman','wansi');

kid.list.push('2');

console.log(kid.sex);
console.log(kid.name);
console.log(kid.list);

console.log(kid2.sex);
console.log(kid2.name);
console.log(kid2.list);
console.log(kid instanceof Parent);

复制父类构造函数内的属性
优点:
1.避免了引用类型的属性被所有实例共享
2.可以在Child中向Parent传参
缺点:
1.只是子类的实例,不是父类的实例
2.方法都在构造函数中定义,每次创建实例都会创建一遍方法

组合继承

组合 原型链继承 和 借用构造函数继承
背后的思路是:使用原型链实现对原型方法的继承,而通过借用构造函数来实现对实例属性的继承。

function Parent(name){
this.name = name;
this.list = [1,2,3]
}

Parent.prototype.say = function(){
console.log(this.name);
}


function Child(age, name){
Parent.call(this,name)
this.age = age;
}

Child.prototype = new Parent();

var kid = new Child(12,'lisi');
var kid2 = new Child(13,'hhh');

kid.say();
kid2.say();

kid.list.push(5);

console.log(kid.list)
console.log(kid2.list)

优点:融合原型链继承和构造函数的优点,是JavaScript中最常用的继承模式
缺点:调用了两次父类构造函数
(组合继承最大的问题是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部)

寄生组合式继承

function Parent (name){
		this.name = name;
		this.list = [1,2,3]
	}

	Parent.prototype.say = function(){
		console.log(this.name)
	}

	function Child(name,age){
		Parent.call(this,name)
		this.age = age;
	}

	function prototype(child,parent){
		var prototype = Object.create(parent.prototype);
		prototype.constructor = child;
		child.prototype = prototype;
	}

	prototype(Child,Parent);

	var child = new Child('xiaohua', 18);

	child.say(); //xiaohua

es5写法

function Parent(name){
            this.name = name;
            this.colors = ['red', 'blue', 'green'];
        }

        Parent.prototype.sayName = function(){
            console.log(this.name);
        }

        function Child(name,age){
            Parent.call(this,name); 
            this.age = age;
        }

        function CreateObj(o){
            function F(){};
            F.prototype = o;
            return new F();
        }

        // Child.prototype = new Parent(); // 这里换成下面
        function prototype(child,parent){
            var prototype = CreateObj(parent.prototype);
            prototype.constructor = child;
            child.prototype = prototype;
        }
        prototype(Child,Parent);

        var child1 = new Child('xiaopao', 18);
        console.log(child1); 

优点: 这种方式的高效率体现它只调用了一次Parent构造函数,并且因此避免了再Parent.prototype上面创建不必要的,多余的属性。普遍认为寄生组合式继承是引用类型最理想的继承方式

9、http协议中get和post的区别

1.GET使用URL或Cookie传参。而POST将数据放在请求体中。
2.GET的URL会有长度上的限制,而POST的数据则可以非常大。
3.POST比GET安全,因为数据在地址栏上不可见。

实际上是没有区别的,都是http底层TCP/IP决定的。
对于GET和POST的理解,是纯粹地来源于HTTP协议。他们只有一点根本区别,简单点儿说,一个用于获取数据,一个用于修改数据。具体的请参考RFC文档。
如果一个人一开始就做Web开发,很可能把HTML对HTTP协议的使用方式,当成HTTP协议的唯一的合理使用方式。从而犯了以偏概全的错误。

在这里插入图片描述
在这里插入图片描述

10、WEB应用从服务器主动推送Data到客户端有那些方式?

  1. html5 websocket
    (WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
    WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。)
  2. WebSocket 通过 Flash
  3. XHR长时间连接
  4. XHR Multipart Streaming
  5. 不可见的Iframe
  6. <\script>标签的长时间连接(可跨域)

Javascript数据推送

Commet:基于HTTP长连接的服务器推送技术

基于WebSocket的推送方案

SSE(Server-Send Event):服务器推送数据新方式

11、浏览器本地存储数据有哪些方法,有什么区别?

cookie,localstorage,sessionstorage,而其实还有userData和IndexedDB这两种数据存储
点击查看

12、你怎么看待前端程序员

对前端界面工程师这个职位是怎么样理解的?它的前景会怎么样?

前端是最贴近用户的程序员,比后端、数据库、产品经理、运营、安全都近。

1、实现界面交互

2、提升用户体验

3、有了Node.js,前端可以实现服务端的一些事情

前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到100 分,甚至更好,

参与项目,快速高质量完成实现效果图,精确到1px;

与团队成员,UI设计,产品经理的沟通;

做好的页面结构,页面重构和用户体验;

处理hack,兼容、写出优美的代码格式;

针对服务器的优化、拥抱最新前端技术。

你如何优化自己的代码?

前端的性能优化主要分为三部分:

HTML优化
避免 HTML 中书写 CSS 代码,因为这样难以维护。
使用Viewport加速页面的渲染。
使用语义化标签,减少 CSS 代码,增加可读性和 SEO。
减少标签的使用,DOM解析是一个大量遍历的过程,减少不必要的标签,能降低遍历的次数。
避免 src、href等的值为空,因为即时它们为空,浏览器也会发起 HTTP 请求。
减少 DNS 查询的次数。

CSS优化
优化选择器路径:使用 .c {} 而不是 .a .b .c {}。
选择器合并:共同的属性内容提起出来,压缩空间和资源开销。
精准样式:使用padding-left: 10px 而不是 padding: 0 0 0 10px。
雪碧图:将小的图标合并到一张图中,这样所有的图片只需要请求一次。
避免通配符:.a .b * {} 这样的选择器,根据从右到左的解析顺序在解析过程中遇到通配符 * {} 会遍历整个DOM,性能大大损耗。
少用 float:float 在渲染时计算量比较大,可以使用 flex布局。
为 0 值去单位:增加兼容性。
压缩文件大小,减少资源下载负担。

JavaScript优化

尽可能把 <\script> 标签放在 body 之后,避免JS 的执行卡住 DOM 的渲染,最大程度保证页面尽快地展示出来。
尽可能合并 JS代码:提取公共方法,进行面向对象设计等……
CSS 能做的事情,尽量不用JS 来做,毕竟 JS 的解析执行比较粗暴,而CSS 效率更高。
尽可能逐条操作 DOM,并预定好 CSS 样式,从而减少 reflow 或者 repaint的次数。
尽可能少地创建 DOM,而是在HTML 和 CSS中使用 display: none 来隐藏,按需显示。
压缩文件大小,减少资源下载负担。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值