字节跳动(今日头条)前端面试

面试问题

字节提前两天约了面试,在晚上七点半,面试的岗位是前端高级开发工程师,面试官很和蔼首先上来做了下简单的自我介绍,然后看了简历的一段经历让我说了一下,问了我是倾向于前端还是后端,然后就进入了正式的面试环节。

  • typeof 和 instanceof 区别 instanceof 是否可以判断自定义的数据类型
1. typeof 用来判断数据的类型 typeof判断所有变量的类型 返回值有 string number boolean object function undefined
2. typeof 对于丰富的对象实例,只能返回"Object"字符串。
3. instanceof 用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象,否则会报错!其返回值为布尔值。
4. instanceof 可以对不同的`对象实例`进行判断,判断方法是根据对象的`原型链`依次向下查询,如果obj2的原型属性存在obj1的原型链上,(obj1 instanceof obj2)值为 true5. instanceof 是可以判断我们自定义的数据类型的
	const Person = function(){}
	var person = new Person()
	person instanceof Person  // true 
	person instanceof Object  // true

  • vue 中数据绑定根据什么原理来改变 DOM 中的数据
// vue 中实现的数据的双向绑定 其实使用了 订阅发布模式  使用 Object.defineProperty 来劫持监听各个属性的变化 ,
// 当属性发生变化后通知订阅者 触发更新回调函数 重新渲染

可以参考这个博客写的 vue 双向绑定原理

  • apply() 、call() 有什么区别
	JavaScript中的每一个Function对象都有一个apply()方法和一个call()方法,它们的语法分别为:
	定义:调用一个对象的一个方法,用另一个对象替换当前对象。
	例如:B.apply(A, arguments)B.call(A,args,args2);即使得 A 对象可以使用 B 对象的方法,改变了 B  对象 this 的指向,B 对象中原本 this 指向的是 B 对象,经过 call(thisObj,arg1,arg2...) 或者 apply(thisObj,arguments)this 指向了 thisObj 。
	且 如果 apply 和 call 中不传入任何参数 那么 this 指向了 Global(全局)
不同点
	1. apply 最多只能传两个参数  第一个参数是新的 this 对象 第二个参数是一个参数数组,其他参数可以写进这个数组中。
	2. call 它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。
	3. 实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。
	4. 还有一个 bind() 方法 它的返回值是一个函数 需要调用执行

示例代码
  // call()、apply()、bind() 重新指向对象的 this 第一个参数都是 this 的指向对象
	var name="小王",age=17;// window 的属性 
	var obj={
		name:"小张",
		age:age,
		Fun:function(fm,to){
			console.log( this.name + "年龄:" + this.age + ";来自:" + fm +"; 去往:" + to);
		},
		child:{
			name:"小张的儿子",
			age:4,
			say:function(fm,to){
				console.log( this.name + "年龄:" + this.age + ";来自:" + fm +"; 去往:" + to);
			}
		}
	}
	var db={
		name:"伽罗;",
		age:23
	}

	// 输出
	obj.Fun(); //小张年龄:17 this 指向了 定义它的 obj
	obj.Fun.call();// 小王年龄:17 this 指向了 window
	obj.Fun.call(db,"成都","上海");// 伽罗;年龄:23;来自:成都; 去往:上海  this 指向了 db

	obj.Fun.apply(); // 小王年龄:17  this 指向了 window
	obj.Fun.apply(db,["成都","上海"]);// 伽罗;年龄:23 this 指向了 db

	obj.Fun.bind()();// 小王年龄:17 this 指向了 window
	obj.Fun.bind(db,["成都","上海"],"aaa")();// 伽罗;年龄:23;来自:成都,上海; 去往:aaa this 指向了 db
5. 补充一个 arguments.callee
- argumnets 该 对象 代表正在 执行的函数和调用它的函数 的参数。是指函数调用传入的参数的数组 (类数组) 
- arguments 有个属性 callee 是个指针 指向拥有这个 arguments 对象的函数。 应用:如 阶乘 setTimeout() 模拟 setInterval()
	setTimeout(function(){
		setTimeout(arguments.callee,2000)
	},2000)
6. 容易混淆的 caller;
- caller 不是 arguments 的属性,它是 Function 的属性 
	funtion a(){
		b();
	}
	funtion b(){
		console.log(b.caller)
	}
	// 执行 a() 
	a() // 输出是 a 方法  顾明思议  b.caller  指 b 函数的调用者 即 谁调用了 b 在执行 a() 的时候 显然在 a 方法体中调用了 b 所以输出的是 a 方法
		
apply的一些其他巧妙用法
	1.Math.max 可以实现得到数组中最大的一项:Math.max(1,2,3,4) 
	Math.max 不支持直接传入数组 比如 Math.max([1,2,3])  这样是不对的 会输出 NaN
	使用 apply 可以这样实现  Math.max.apply(null,[1,2,3,4])  // 输出 4  apply 会将数组转换成 一个接一个参数传递给方法。
	同样 Math.min 是不是都可以这样呢? // 是的
	2. Array.prototype.push 数组对象的原型实例方法push 提供了 push(item1,item2,...item) 同样我们也可以使用 apply 方法进行数组的合并  数组合并可以使用 contact
	[].push.apply([1,2],[4,5]) // 返回的是新数组的长度  感觉实用性不强
  • 写代码:实现 ES6 语法中的 const 声明 使用 ES5 var 怎么去做
// 使用es5 的语法 去实现 ES6 中的 const 的声明
// 首先我们要知道 const 有什么特性:
- 不能重新定义
- 不能重新赋值
- 语义化标识,表示声明后不可更改的不变量
- 声明时 完成 初始化
// 本质上:const 所保证的并不是变量的值不可改变 而是 变量所指向的内存地址不可改变 简单的数据类型保存在内存地址中 等同于常量
	var _const=function(param,value){
		// 使用一个对象 这里设置成 window
		var _global = window;
		// 判断要声明的 param 是否合法   不可以是关键字
		var key_arr = ['class','var','let','const','return']// 还可以在增加限定关键字
		if(!param || key_arr.indexOf(param)>-1){
			throw new Error(`${param} 属于关键字 声明不合法`)
		}
		// 判断是否已经存在了
		if(_global.hasOwnProperty(param)){
			throw new Error(`${param} 已经被声明过了`)
		}
		// 给 _global 添加属性 param 
		_global[param] = value;
		// 使用定义属性方法  defineProperty
		Object.defineProperty(_global,param,{
			get:function(){
				return value;
			},
			set:function(){
				// 检查赋值 已经存在了 不可再进行赋值
				if(_global.hasOwnProperty(param)){
					throw new Error(`${param} 不可再进行赋值`)
				}
				return value;
			}
		})
	}
	_const('TEST', "test_value"); 
	console.log("TEST",TEST);
	//_const('TEST', "test_value"); // Uncaught Error: TEST 已经被声明过了
	TEST = "9999"//Uncaught Error: TEST 不可再进行赋值

	console.log("TEST2",TEST);
  • 写代码:输入一串含有 ()、[] 、{ } 的字符串 写代码做出检查 括号要成对
// 检查合法性 对于一个字符检查括号的合法性 如 () [] {}
	var checker = (str)=>{
		var len = str.length;
		if(len <= 1){
			return false;
		}
		// 定义三个空数组 采用进栈出栈的方式去做判断
		var arr_little = [] ,arr_middle = [], arr_big = [];
		for(var i = 0 ; i < len ; i++){
			if(str[i]==="("){
				arr_little.push("(");
			}else if(str[i]===")"){
				if(arr_little.length==0){
					return false;
				}
				arr_little.pop();
			}else if(str[i]==="["){
				arr_middle.push("[");
			}else if(str[i]==="]"){
				if(arr_middle.length==0){
					return false;
				}
				arr_middle.pop();
			}else if(str[i]==="{"){
				arr_big.push("{");
			}else if(str[i]==="}"){
				if(arr_big.length==0){
					return false;
				}
				arr_big.pop();
			}else{
				return false
			}
		}
		// 判断 数组的个数为0
		if(arr_little.length==0 && arr_middle.length==0 && arr_big.length == 0){
			return true;
		}
		else
			return false;
	}
  • 写代码:输入一个有序数组 输出一个无序数组
function randArr(arr){
	let len=arr.length;
	for(let i = 0;i < len;i++ ){
		let index=parseInt(Math.random()*len-1);
		let temp=arr[i];
		arr[i]=arr[index];
		arr[index]=temp;
	}
	return arr;
}
let arrNew=[1,2,3,4,5];
console.log(randArr(arrNew));
  • Promise 以及 它有几种状态呢
Promise  对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.
// Promise 是一种异步处理 有三种状态  pending (初始化状态) fulfilled (执行完成成功) rejected (执行失败)
// 当状态发生改变了就会去触发 then() 方法 无论是 pending-->fulfilled  还是 pending-->rejected 的状态都可以触发 then()
/* 优点 
	* 1 解决回调
	* 2 解决嵌套
	* 3 分离链式调用 
	*/
// 1. 实例化Promise
	var myPromise = new Promise(function(resolve,reject) {
		// body...
		console.log("promise 的 创建完成 ");
		setTimeout(function(){
			resolve();
		},3000)
	});
	myPromise.then(function(){
		console.log("成功 回调")
	})
  • 怎么产生的跨域 几种解决方法 都是怎么解决的
// 浏览器的同源策略 即相同协议 端口 域名 下允许相互通信  三者有一个不同便会引起跨域问题
1.jsonp的方式,只针对于get请求
2. window.domain 在不同源中设置 相同的 window.domain 来实现跨域  但是局限于 基础域相同、协议端口都要相同
3. window.name+iframe 常用 
	在父页面上有个iframe嵌入了异源的html 异源的html中将数据赋值给window.name 
	父页面获取数据前,将iframe中的异源html替换为同源的html 此时里面的window.name 不会因为src改变而改变,所以就得到了来自异源的数据
4. CORS 服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
5. H5 中新引进的 window.postMessage()
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值