整理一下最近面试问的比较多的问题

1、最常见的就是 JS的基本数据类型有哪些?

number、string、bootlean、null、undefined、Bigint 、Symbol

2、常见的内置对象

object是所有对象的父对象
数据封装类对象:Object 、 Array 、 Boolean 、 Number 和 String
其他对象:function、Arguments math date

3、你是怎么理解闭包的?

闭包就是能够访问函数变量的函数就是闭包
优点 可以实现数据的私有化
缺点 使用不当会造成内存泄漏
闭包应用广泛:比如我们的防抖、节流这些

4、作用域和作用域链

作用域就是我们声明的函数或变量的可访问范围就是作用域
作用域链就是放我们在访问一个变量的时候 当前作用域没有 就会往上一层的作用域访问 直到访问window为值

5、原型和原型链

每个对象都会在其内部初始化一个属性,prototype,这个就是原型
当我们访问一个方法的时候,当前的对象没有 就会往他的原型上继续查找,这个prototype也有自己的原型 一直往上 直到找到object为止 这个一层一层往上找就是原型链

 function pro() {
            this.name = '张三'
        }
        pro.prototype.name = "里斯"
        var a = new pro()
        console.log(a.name);
        console.log(a.__proto__ === pro.prototype); // true

6、什么是事件委托?

事件委托就是事件代理,把自身要绑定的事件交给父级来绑定 原理就是使用事件冒泡来实现的,使用事件代理可以减少我们的事件注册 从而提高性能 减少内存的占用

7、实现继承的方法有那些

继承是什么意思呢?为什么要继承
让一个对象可以访问到另一个对象中的属性和方法

继承的方法比较多我就说两三个把
第一就是通过原型链继承

 //    1、通过原型来继承
        function Parent() {
            this.name = "父"
        }
        Parent.prototype.say = function () {

            console.log(this.name);

        }
        function Child() {
            this.age = 18
        }
        Child.prototype = new Parent()

        let child = new Child()
        child.say();

第二是通过构造函数继承 这个是无法使用到父类的原型

 function Parent1() {
            this.age = 22
        }
        Parent1.prototype.fn = function () {
            console.log(this.age);
            // return "parent1"
        }
        function Child1() {
            Parent1.call(this)
        }
        let child1 = new Child1()
        console.log(child1);

第三就是组合式的
组合继承综合了原型链继承和盗用构造函数继承(构造函数继承),将两者的优点结合了起来

function Parent2() {
            this.name = "父2"
        }
        Parent2.prototype.say = function () {
            console.log(this.name);
        }

        function Child2() {
            this.age = 12
            Parent2.call(this)
        }
        Child2.prototype = new Parent2()
        let child2 = new Child2()
        console.log(child2);
        child2.say()

8、类的创建

es5: new一个函数,在这个函数的原型里面添加属性和方法`

function Aa(name){
    this.name = name
}
Aa.prototype.hello = funciton(){
    alert(this.name)
}

es6直接使用 class

class {
    constructor(name){
        this.name = name
    }
    hello(){
        alert(this.name)
    }
}

9、谈一下你对this的理解

this这个问题也是问的比较多的了

  1. 一般情况下this是指向window的,如果是严格模式他就指向undefined
  2. 我们可以通过call apply bind来修改this的指向
  3. new出来的实例对象this是指向这个实例的
  4. 在隐士的状态下是指向他调用者

10、箭头函数和普通函数的区别

  1. 箭头函数是没有this的 他的this是指向他上一层函数的
  2. 箭头函数没有 arguments 没有原型
  3. 箭头函数不能使用 new

11、new 操作符具体做了什么?

  1. 创建空对象
  2. 把函数的原型给到空对象
  3. 修改this指向
  4. 返回值
function new(fn,...agrs){

	let obj = {}
	Object.setPrototypeOf(obj,fn.prototype)
	let res = fn.apply(obj,...agrs)
	return typeof res ==== 'object'?res :obj
}

11、写一个简易版的AJAX

function ajax(options){
//new xml
let xhr = new XMLHttpRequest()
// 要请求的地址和方法
xhr.open(options.method,options.url)
//发送请求
xhr.send()
//监听返回的数据
xhr.onreadystatechange = function(){
	
	if(xhr.readyState === 4){
		if(xhr.status ==200){
			console.log(xhr.responseText)
		}
	}

}

}

12、如何解决跨域问题?

  1. JSONP
  2. 资源共享
  3. node代理
  4. nginx 代理

13、null,undefined 的区别

null:是定义一个对象被定义为空
undefined是没有这个值 这个值不存在

14、谈谈你对ES6的理解

  1. 箭头函数
  2. promise
  3. 模板字符串
  4. 扩展运算符
  5. let 和 const

15、怎么把异步代码改成同步的

使用 async和await

16、promise解决了什么问题

回调地狱的问题,面试官又会问你什么是回调地狱
回调地狱就是函数嵌套函数 多层的嵌套

17、如何通过JS判断一个数组

var arr = []
可以使用es6新增的属性 Array.isArray Array.isArray(arr) // true
instanceof arr instanceof Array // true

18、typeof是干什么的?

检查数据类型的
追问 可以检查那些数据类型
number string boolean undefined function object
如果是null的话返回是什么?为什么
null的话他是返回一个 object ,以为null的低位符为 000 也就是object 所以他返回 object
那么我们定义一个函数 怎么让null返回的是null
我们可以使用 switch

function typeof(obj){
	
	switch(obj){
		case null:
			return 'null'
		defalt:
			return obj["constructor"].name
		
	}

}

19、深浅拷贝?

浅拷贝:复制对象的内存地址,当某一个对象修改了数据 那个另外一个就会跟着改变,他们是互相影响的
深拷贝:重新开闭一个新的内存地址 然后把值一个一个放进去

实现:
浅拷贝可以通过 直接赋值 object.assig …扩展运算符来实现

深拷贝则 json.parse(JSON.stringify(obj)) 有缺点就是值是undefined的时候和函数会忽略 那么我们可以使用递归来实现

function clone(obj){
	// 判断是否为对象 如果不是直接返回
	if(typeof obj !== 'object') return 
	// 如果是数组就创建数组 否则就创建对象
	let newObj = obj instanceof Array ?[]:{}
	// 用for of循环
	for(let key of obj){
		newObj[key] = typeof obj[key] === 'object'?clone(obj[key]):obj[key]
	}
//返回
return newObj
}

20、手写防抖、节流函数

  1. 防抖:我们定义一个时间n秒之后执行这个函数 如果在n秒内又被触发了就重新计算
  2. 节流:定义一个时间点 n 秒 n秒内只会执行一次函数

防抖

	  <input type="text">
        var input = document.querySelector('input')
        function fn() {
            console.log('执行函数');
        }
        function Shake(fn, wait = 1000) {

// fn是传入的函数 wait是时间
function Shake(fn,wait=200){
	let timer = null;
	return function{
	//进来先清除定时器
	  clearTimeout(timer)
		timer = setTimeout(()=>{
			fn.apply(arguments )
		},wait)
	}

}

节流


function jieliu(fn,wait=200){
	
	let old = 0
	return function{
		
		let now = new Date().getTime()
		if(now-old>wait || old==0){
			setTime(()=>{
			fn.apply(arguments )	
			old = now
			},wait)
		}

}
}

今天就先更新到这里把 大家看看哈 如果有错误帮我纠正纠正 下一篇更新手撕面试题

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐