javaScript面试题(含答案)

本文深入探讨JavaScript中的闭包概念,揭示其在内存管理和性能上的挑战。同时,介绍了原型和原型链的工作原理,以及如何利用原型实现继承。递归和尾递归优化是函数式编程的关键,文中展示了如何避免栈溢出。最后,阐述了AJAX的工作流程,并讨论了多种跨域解决方案,如CORS、JSONP和代理服务器等。
摘要由CSDN通过智能技术生成

闭包

闭包就是函数能够记忆住当初定义时候的作用域,不管函数到哪里执行了,永远都能够 记住那个作用域,并且会遮蔽新作用域的变量。可预测状态容器;实现模块化,实现变量的私有封装;可以实现迭代器。 闭包缺点:1.闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅 因为它常驻内存,更重要的是,对闭包的使用不当的话会造成无效内存的产生;2.性能问题 使用闭包时,会涉及到跨作用域访问,每次访问都会导致性能损失。 因此在脚本中,最好小心使用闭包,它同时会涉及到内存和速度问题。不过我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响。


原型和原型链

原型:每一个对象类型都有一个隐式原型__ proto __ ,每一个函数都有一个显示原型prototype,该属性指向它的原型对象。

原型链:某个对象的原型又有自己的原型,直到某个对象的原型为null为止,组成这条的最后一环,这种一级一级的链就是原型链。


递归和递归优化

递归就是函数自己调用自己。但是又不能无限的调用自己,需要有一个出口,否则会成为死循环。函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

// 循环求1-5的所有数的和
var sum = 0;
for(var i = 1; i <= 5; i++){
	sum += i;
}
console.log(sum) // 15

//递归实现1-5的所有数的和
function sum(n){
	if(n === 1){
		return 1;
	}
	return n + sum(n-1);
}
console.log(sum(5)); //15

尾递归优化是解决递归调用栈溢出的方法。尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

// 上例递归进行尾递归优化
function sum(n, m = 0){
	if(n === 1){
		return 1 + m;
	}
	return sum(n-1, n + m);
}
console.log(sum(5)); //15

// 或者while优化
function sum(n, m = 0){
	while(n >= 1){
		return sum(n - 1, n + m);
	}
	return m;
}
console.log(sum(5)); // 15

ajax工作原理和封装

1.创建XMLHttpRequest对象。 2.设置请求方式。open() 3.调用回调函数。onreadystatechange 4.发送请求。send()

 function ajax(options) {
        const { type, dataType, data, timeout, url, success, error } = options;
        var params = formatParams(data);
        var xhr;
        //考虑兼容性
        if (window.XMLHttpRequest) {
          xhr = new XMLHttpRequest();
        } else if (window.ActiveObject) {
          //兼容IE6以下版本
          xhr = new ActiveXobject("Microsoft.XMLHTTP");
        }
        //启动并发送一个请求
        if (type == "GET") {
          xhr.open("GET", url + "?" + params, true);
          xhr.send();
        } else if (type == "POST") {
          xhr.open("post", url, true);
          //设置表单提交时的内容类型
          //Content‐type数据请求的格式
          xhr.setRequestHeader(
            "Content‐type",
            "application/x‐www‐form‐urlencoded"
          );
          xhr.send(params);
        }

        // 设置有效时间
        setTimeout(function () {
          if (xhr.readySate != 4) {
            xhr.abort();
          }
        }, timeout);

        // 接收
        // options.success成功之后的回调函数 options.error失败后的回调函数
        //xhr.responseText,xhr.responseXML 获得字符串形式的响应数据或者XML形式的响应数据
        xhr.onreadystatechange = function () {
          if (xhr.readyState == 4) {
            var status = xhr.status;
            if ((status >= 200 && status < 300) || status == 304) {
              success && success(xhr.responseText, xhr.responseXML);
            } else {
              error && error(status);
            }
          }
        };
      }

      //格式化请求参数
      function formatParams(data) {
        var arr = [];
        for (var name in data) {
          arr.push(
            encodeURIComponent(name) + "=" + encodeURIComponent(data[name])
          );
        }
        arr.push(("v=" + Math.random()).replace(".", ""));
        return arr.join("&");
      }

跨域

跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。其 实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。同源策略SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地 址,也非同源。

方法1:跨域资源共享CORS跨域,就是服务端在HTTP返回头上加上“AccessControll-Allow-Origin:*”。 “Access-Controll-Allow-METHODS:GET, POST” DELETE、PATCH请求类型会发出OPTIONS预检请求。

方法2:代理跨域,webpack-dev-server里面的proxy配置项。config中的 ProxyTable

方法3:JSONP,利用页面srcipt没有跨域限制的漏洞,用script的src引入它,然后页 面内定义回调函数,jQuery中$.ajax({dataType: ‘jsonp’})。

方法4: iframe跨域,配合window.name或者 location.hash或者document.domain 一起使用

方法5:nginx反向代理接口跨域,通过nginx配置一个代理服务器(域名与domain1 相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中 domain信息,方便当前域cookie写入,实现跨域登录。

方法6:jquery的ajax跨域,dataType:'jsonp'

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值