前端面试题之第六弹

一、手写数组去重,多种方法

var arr = [1,2,3,4,4,2,2,6,9,1,0];
		var obj = {};
		arr.forEach(e=>{ //把arr的信息统计到obj里面
			if(obj[e]===undefined){ //其实是利用对象属性是否存在做了一层遍历
  				obj[e] = 1
			}else{
				obj[e]++
			}
		})
		console.log(Object.keys(obj))
		//结果:[0,1,2,3,4,6,9]
var arr = [1,2,3,4,4,2,2,6,9,1,0];
		var newArr = []; 
		for(var i = 0;i < arr.length;i++){
		 var onOff = true;
			for(var j = 0;j < newArr.length;j++){
				if(newArr[j]==arr[i]){ 
					//如果arr数组的数据和新数组的数据相等的话,也就是重复了
					//则把状态onOff改为false,并且跳出当前循环
					onOff = false;
					break
				}
			}
			if(onOff){
				//如果新数组中没有这个arr数组中的数据
				//那么状态onOff的值还是true
				newArr.push(arr[i]);
			}
		}
		console.log(newArr)
		//结果:[1,2,3,4,6,9,0]
var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2];
		var newArr = [];
		for (var i = 0; i < arr.length; i++) {
			if (newArr.indexOf(arr[i]) === -1) {
				//这个方法很好理解,利用了indexOf()方法,如果查询不到则返回-1
				//如果没有直接添加到newArr中
				newArr.push(arr[i])
			}
		}
		console.log(newArr)
		//结果:[2,8,5,0,6,7]

二、浏览器是如何渲染页面的

浏览器解析

  1. 浏览器通过请求的 URL 进行域名解析,向服务器发起请求,接收文件(HTML、CSS、JS、Images等等)。
  2. HTML 文件加载后,开始构建 DOM Tree
  3. CSS 样式文件加载后,开始解析和构建 CSS Rule Tree
  4. Javascript 脚本文件加载后, 通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree

浏览器渲染

  1. 浏览器引擎通过 DOM Tree 和 CSS Rule Tree 构建 Rendering Tree
  2. Rendering Tree 并不与 DOM Tree 对应,比如像 标签内容或带有 display: none; 的元素节点并不包括在 Rendering Tree 中 。
  3. 通过 CSS Rule Tree 匹配 DOM Tree 进行定位坐标和大小,是否换行,以及 position、overflow、z-index 等等属性,这个过程称为 Flow 或 Layout 。
  4. 最终通过调用Native GUI 的 API 绘制网页画面的过程称为 Paint
    浏览器渲染结构

三、call,apply,bind方法得作用分别是什么

call(),apply(),bind()都是用来重定义this这个对象的。

var name = '漩涡鸣人',age = 6;
var obj = {
    name : '宇智波鼬',
    objAge: this.age,
    myLove:function(){
        console.log( this.name +"年龄"+ this.age);
    }
}
var mw= {
    name : '自来也',
    age: 88
}
obj.myLove.call(mw); //自来也年龄88
obj.myLove.apply(mw); //自来也年龄88
obj.myLove.bind(mw)(); // 自来也年龄88

—以上除了bind方法后面多了一个()外,结果返回都一致。
—由此得出结论,bind返回的是一个新的函数,你必须调用它才会被执行。

对比call、apply、bind传参的情况

var name = '漩涡鸣人',age = 6;
var obj = {
    name : '宇智波鼬',
    objAge: this.age,
    myLove:function(fm,t){
        console.log( this.name +"年龄"+ this.age,"来自" + fm + "去往" + t );
    }
}
var mw= {
    name : '自来也',
    age: 88
}
obj.myLove.call(mw,'火之国','木叶村'); //自来也年龄88来自火之国去往木叶村
obj.myLove.apply(mw,['火之国','木叶村']); //自来也年龄88来自火之国去往木叶村
obj.myLove.bind(mw,'火之国','木叶村')(); // 自来也 年龄88 来自火之国去往木叶村
obj.myLove.bind(mw,['火之国','木叶村'])(); // 自来也 年龄88 来自火之国木叶村去往undefined

从上面的四个结果不难看出
—call,bind,apply这三个函数的第一个参数都是this的指向对象,直到第二个参数差别就出来了。
—call的参数是直接放进去的,直接用逗号分离;
—apply的所有参数都必须放在一个数组里面传进去;
—bind除了返回是函数以外,它的参数和call的放入方式一样。
它们三者的参数不限定是string类型,允许是各种类型,包括函数、对象等等。

总结

—call,apply,bind都是可以改变函数体内this的指向。
—call,apply,bind使用时,传入的第一个参数都是用来传递this的指向的,也就是对上下文的指定。
—call,apply,bind都是可以传入多个参数,不同的是,call和bind的后续参数都是按照顺序传参,而apply的传参类型是数组;bind的参数可以在函数执行的时候再次添加。

未完待续…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值