javascript的自我面试总结

1.谈谈JS的类型转换机制

1.显示转换 --> (方法触发) such as: Number、String、Boolean、ParseInt
2.隐式转化 -->(计算时触发)

2.深拷贝浅拷贝的区别?如何实现一个深拷贝?

1.浅拷贝
	(1.1)浅拷贝是拷贝基本数据的值和拷贝复杂数据的地址,当原数据或者拷贝数据其中之一发生变化时,两者都会改变。
	(1.2)实现方式:Object.assign() 注意:当原数据只有一层时,该方法是深拷贝。
2.深拷贝
	(2.1)深拷贝是开辟一个新的空间存储原数据的初始数据,当原数据或者拷贝数据其中之一发生变化时,两者互不干扰。
	(2.2)实现方式:JSON.parse(JSON.stringify(obj))、或者写个循环递归函数。

3.说说对闭包的理解

1.函数套函数
2.作用:创建私有变量、延长变量的生命周期

4.说说你对作用域链的理解

1.一般将作用域分成:全局作用域、函数作用域、块级作用域
2.由局部作用域向上查找、直到找到全局作用域的整个过程形成一种链式结构叫做作用域链。

5.JavaScript原型,原型链 ?

1.每个对象的__proto__都是指向它的构造函数的原型对象prototype的
person1.__proto__ === Person.prototype

2.构造函数是一个函数对象,是通过 Function构造器产生的
Person.__proto__ === Function.prototype

3.原型对象本身是一个普通对象,而普通对象的构造函数都是Object
Person.prototype.__proto__ === Object.prototype

4.刚刚上面说了,所有的构造器都是函数对象,函数对象都是 Function构造产生的
Object.__proto__ === Function.prototype

5.Object的原型对象也有__proto__属性指向null,null是原型链的顶端
Object.prototype.__proto__ === null

6.下面作出总结:
一切对象都是继承自 Object 对象,Object 对象直接继承根源对象null
一切的函数对象(包括 Object 对象),都是继承自 Function 对象
Object 对象直接继承自 Function 对象
Function对象的__proto__会指向自己的原型对象,最终还是继承自Object对象

6.typeof与instance of的区别?Object.prototype.toString.call的使用

1.typeof 会返回一个变量的基本类型	<-->	instanceof 返回的是一个布尔值
2.typeof 能检测除null外的基本数据类型,引用类型除了function外都不能检测。	<-->	instanceof 只能检测复杂数据类型。
3.Object.prototype.toString.call() 的使用
    function getType(obj) {
        let type = typeof obj;
        if (type !== "object") {    // 先进行typeof判断,如果是基础数据类型,直接返回
            return type;
        }
        // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
        return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
    }
	console.log(null) // Null
	console.log(undefined)	// undefined
	console.log([])	// Aaary
	console.log({})	// Object
	console.log(function(){})	// function

7.ajax原理是什么?如何实现?

1.原理:通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面
2.如何实现?
	(2.1)创建XMLHttpRequest对象 const xhr = new XMLHttpRequest();
	(2.2)与服务器建立连接	xhr.open(method, url, [async][, user][, password])
	(2.3)给服务端发送数据	xhr.send([body])
	(2.4)绑定onreadystatechange事件
    	request.onreadystatechange = function(e){
            if(request.readyState === 4){ // 整个请求过程完毕
                if(request.status >= 200 && request.status <= 300){
                    console.log(request.responseText) // 服务端返回的结果
                }else if(request.status >=400){
                    console.log("错误信息:" + request.status)
                }
            }
        }

8.bind、call、apply 区别?

1.第一个参数为undefined或者null,默认指向全局window。
2.call是参数列表,apply是参数数组,bind都可。
3.call、apply是一次性传入参数,bind可多次传入。
4.call、apply会立即执行一次函数,bind会返回一个改变this指向后的函数。
	call/apply:	fn.call(obj, options) / fn.aplly(obj, [options])
	bind:	const resFn = fn.bind(obj, 1/[options])
			resFn() / fn.bind(obj, 1/[options])()

9.说说你对事件轮询(事件循环) EventLoop 的理解

1.JS代码执行的一种机制。
2.微任务:Promise.then()、MutaionObserver、Proxy、process.nextTick(Node.js)
3.宏任务:计时器、setImmediate、I/O(Node.js)、
4.执行机制
	首先整个JS代码是宏任务,执行完所有同步任务,然后执行异步任务,因为最外层是宏任务,所以从微任务开始执行,清空全部微任务,再		进入下一次宏任务,执行完宏任务,然后再判断是否有微任务,没有则进行下一次宏任务,有则清空微任务,直到所有宏、微任务清空			完为止,最后执行宏任务。
	例子:
		console.log(1)
        setTimeout(()=>{
            console.log(2)
        }, 0)
        new Promise((resolve, reject)=>{
            console.log('new Promise')
            resolve()
        }).then(()=>{
            console.log('then')
        })
        console.log(3)
		// 1 new Promise 3 then 2

10.说说你对尾递归的理解。有哪些应用场景?

1.什么是尾递归?在函数尾部调用的是函数自身
	例如:(1.1)普通递归
            function factorial(n) {
              if (n === 1) return 1;
              return n * factorial(n - 1);
            }
            factorial(5) // 120
		  (1.2) 尾递归
            function factorial(n, total) {
              if (n === 1) return total;
              return factorial(n - 1, n * total);
            }
            factorial(5, 1) // 120
2.应用场景:阶乘、数组求和、斐波那契

11.什么是内存泄漏?垃圾回收机制是什么?说说JS中内存泄漏的几种情况?

1.什么是内存泄漏?
	由于疏忽或错误造成程序未能释放已经不再使用的内存
2.不及时释放内存会有什么影响?
	轻则影响系统性能,重则导致进程崩溃
3.什么是垃圾回收机制? 两种方式:(3.1)标记清除(最常用)	(3.2)引用计数
	(3.1)回收规则:
    	1.全局变量不会被回收。    
        2.局部变量会被回收,也就是函数⼀旦运⾏完以后,函数内部的东西都会被销毁。    
        3.只要被另外⼀个作⽤域所引⽤就不会被回收 (闭包中引⽤的变量不会被回收)
	(3.1)标记清除
    		例如:function fn() {
                	let a = 100;
            	  }
				 fn()
			当声明一个fn函数时,进入环境,给a标记‘进入环境’,然后机制会清除所有被标记的变量,当fn()执行后,会给a标记‘离开环			 境’,最后垃圾回收机制会释放内存,回收空间。
	(3.2)引用计数
    		例如:const arr = [1, 2, 3, 4];
					console.log('hello world');
			语言引擎有一张引用表-保存了所有资源的引用次数:数组[1, 2, 3, 4]是一个值,arr是对这个值的引用,所以引用次数是1,              所有它会持续占用内存。
             当arr = null;引用次数就变为0,就会被垃圾回收,内存就会被释放。
3.常见内存泄漏情况:定时器、函数内对全局变量的赋值、通过this赋值的全局变量

12.什么是防抖和节流?如何实现?

1.节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
	function throttled2(fn, delay = 500) {
        let timer = null
        return function (...args) {
            if (!timer) {
                timer = setTimeout(() => {
                    fn.apply(this, args)
                    timer = null
                }, delay);
            }
        }
    }
2.防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
	function debounce(func, wait) {
        let timeout;

        return function () {
            let context = this; // 保存this指向
            let args = arguments; // 拿到event对象

            clearTimeout(timeout)
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
    }
3.目的都是,降低回调执行频率。节省计算资源
4.应用场景?
	防抖在连续的事件,只需触发一次回调的场景有:搜索框搜索输入。只需用户最后一次输入完,再发送请求。
    节流在间隔一段时间执行一次回调的场景有:滚动加载,加载更多或滚到底部监听。
posted @ 2022-05-06 16:10  SKa-M  阅读(31)  评论(0编辑  收藏  举报