JavaScript面试习题练习

1、什么是JavaScript闭包?
答:JavaScript允许使用内部函数,内部函数可以访问他们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数,当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包;
2、闭包的好处是什么?
答:①不增加额外的全局变量;
②执行过程中所有的变量都是在匿名函数内部;
3、闭包的缺点?
答:①由于闭包会使函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会导致网页性能问题,在IE中可能导致内存泄露。解决办法是,在退出函数之前,将不使用的局部变量全部删除;
②闭包会在父函数外部,改变父函数内部变量的指;
4、function a(){return:1;} var a=10;alert(a);弹出框中的值为10;
5、function a(){return:1;} var a;alert(a);弹出框中的值为一个函数Object;
6、JavaScript如何实现继承?

答:通过原型和构造器;
7、如何创建一个对象?

function Person(name,age){
  this.name=name;
  this.age=age;
this.sing=function(){
  alert(this.name)}

8、谈谈对this对象的理解。

答:this是js的一个关键字,随着函数使用场合不同,this的值会发生变化。但是this始终指向的是调用函数的那个对象;this一般情况下,是全局对象Global。作为方法调用,那么this就是指这个对象。
9、说说对作用域的理解。

答:作用域的作用是保证执行环境里有权访问的变量和函数是有序的,作用域的变量只能向上访问,变量访问到window对象即被终止,作用域向下访问变量是不被允许的。
10、var a = “2015”,操作使其变为倒序。

var a = "2015";
var arr = Array.from(a).map(el => Number(el))
arr.sort((a,b) => b-a)
var res = arr.join(",")
console.log(res) //5, 2, 1, 0

11、Dom元素e的e.getAttribute(propName)和e.propName有什么区别和联系?
e.getAttribute(),是标准 DOM 操作文档元素属性的方法,具有通用性可在任意文档上使用,返回元素在源文件中设置的属性
e.propName 通常是在 HTML 文档中访问特定元素的特性,浏览器解析元素后生成对应对象(如 a 标签生成 HTMLAnchorElement),这些对象的特性会根据特定规则结合属性设置得到,对于没有对应特性的属性,只能使用 getAttribute 进行访问
e.getAttribute()返回值是源文件中设置的值,类型是字符串或者 null(有的实现返回"")
e.propName 返回值可能是字符串、布尔值、对象、undefined 等
大部分 attribute 与 property 是一一对应关系,修改其中一个会影响另一个,如 id,title 等属性
一些布尔属性的检测设置需要 hasAttribute 和 removeAttribute 来完成,或者设置对应 property
像link中 href 属性,转换成 property 的时候需要通过转换得到完整 URL
一些 attribute 和 property 不是一一对应如:form 控件中对应的是 defaultValue,修改或设置 value property 修改的是控件当前值,setAttribute 修改 value 属性不会改变 value property

12、offsetWidth/offsetHeight,clientWidth/clientHeight 与 scrollWidth/scrollHeight 的区别是什么?

offsetWidth/offsetHeight包含内容+内边距和+边框,效果与 e.getBoundingClientRect()相同;
clientWidth/clientHeight 包含内容和内边距;
scrollWidth/scrollHeight 包含内容+内边距+溢出内容的尺寸;
13、XMLHttpRequest 通用属性和方法?
readyState:表示请求状态的整数,取值:
UNSENT(0):对象已创建
OPENED(1):open()成功调用,在这个状态下,可以为 xhr 设置请求头,或者使用 send()发送请求
HEADERS_RECEIVED(2):所有重定向已经自动完成访问,并且最终响应的 HTTP 头已经收到
LOADING(3):响应体正在接收
DONE(4):数据传输完成或者传输产生错误
onreadystatechange:readyState 改变时调用的函数
status:服务器返回的 HTTP 状态码(如,200, 404)
statusText:服务器返回的 HTTP 状态信息(如,OK,No Content)
responseText:作为字符串形式的来自服务器的完整响应
responseXML: Document 对象,表示服务器的响应解析成的 XML 文档
abort():取消异步 HTTP 请求
getAllResponseHeaders(): 返回一个字符串,包含响应中服务器发送的全部 HTTP 报头。每个报头都是一个用冒号分隔开的名/值对,并且使用一个回车/换行来分隔报头行
getResponseHeader(headerName):返回 headName 对应的报头值
open(method, url, asynchronous [, user, password]):初始化准备发送到服务器上的请求。method 是 HTTP 方法,不区分大小写;url 是请求发送的相对或绝对 URL;asynchronous 表示请求是否异步;user 和 password 提供身份验证
setRequestHeader(name, value):设置 HTTP 报头
send(body):对服务器请求进行初始化。参数 body 包含请求的主体部分,对于 POST 请求为键值对字符串;对于 GET 请求,为 null

14、focus/blur和focusin/focusout的区别和联系是什么?
focus/blur不冒泡,兼容性好;
focusin/focusout冒泡,在火狐之外的浏览器兼容性保持不错;
可以获得焦点的元素有window、链接被点击或者键盘操作、表单空间被点击或者键盘操作、设置tabindex属性的元素被点击或者键盘操作;

15、mouseover/mouseout 与 mouseenter/mouseleave 的区别与联系?
mouseover/mouseout 是标准事件,所有浏览器都支持;mouseenter/mouseleave 是 IE5.5 引入的特有事件后来被 DOM3 标准采纳,现代标准浏览器也支持
mouseover/mouseout 是冒泡事件;mouseenter/mouseleave不冒泡。需要为多个元素监听鼠标移入/出事件时,推荐 mouseover/mouseout 托管,提高性能
标准事件模型中 event.target 表示发生移入/出的元素,vent.relatedTarget对应移出/如元素;在老 IE 中 event.srcElement 表示发生移入/出的元素,event.toElement表示移出的目标元素,event.fromElement表示移入时的来源元素

16、sessionStorage,localStorage,cookie 区别?
都会在浏览器端保存,有大小限制,同源限制;
cookie会在请求时发送到服务器,服务器可以修改cookie;web storage 不会发送到服务器;
cookie有path概念,子路径可以访问父路径cookie,父路径不能访问子路径cookie;
cookie在设置的有效期内有效,默认为浏览器关闭;sessionStorage 在窗口关闭前有效,localStorage 长期有效,直到用户删除;
共享:sessionStorage 不能共享,localStorage 在同源文档之间共享,cookie 在同源且符合 path 规则的文档之间共享;
localStorage 的修改会促发其他文档窗口的 update 事件;
cookie 有 secure 属性要求 HTTPS 传输;
大小,浏览器不能保存超过 300 个 cookie,单个服务器不能超过 20 个,每个 cookie 不能超过 4k。web storage 大小支持能达到 5M;

17、什么是同源?

1.协议相同;
2.域名相同;
3.端口相同;
18、如何实现跨域通信?

跨域通信:js 进行 DOM 操作、通信时如果目标与当前窗口不满足同源条件,浏览器为了安全会阻止跨域操作。跨域通信通常有以下方法
如果是 log 之类的简单单项通信,新建,

19、JavaScript有哪几种数据类型?

六种基本数据类型:string、null、number、undefined、null、symbol(ES6)
一种引用类型:Object
20、什么是闭包?闭包有什么用?

闭包是在某个作用域内定义的函数,它可以访问这个作用域内所有变量。
闭包作用域通常包括三个部分:
1.函数本身作用域;
2.闭包定义时的作用域;
3.全局作用域;
闭包常见用途:
1.创建特权方法用于访问控制;
2.事件处理程序及回调;

21.给出一个数组,求出数组中总成绩和平均成绩,数组在图里;

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			var str="小红:87;小蓝:81;小花:;小天:87;小章:74;小小:95;小红:87;小红:87;小红:87;小红:87";
			var arr = str.split(';');
			//字符串分割数组
			var pingjun = 0;
			//平均分的分母
			var total = 0;
			//总分
			for(var i=0;i<arr.length;i++){
				var po = arr[i].indexOf(":");
				//查找:位置
				var val = arr[1].substr(po+1);
				//截取:后面的字符
				if(val*1>0){
					pingjun++
				};
				//如果截取的字符转化为数字后大于0,则分母+1
				total+=val*1;
				//累加总分
			}
			alert("总分"+total);
			alert("平均分"+total/pingjun);

			
		</script>
	</body>
</html>

22.给出一个数组,随机出来数组中3个内容,数组如下图;

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<button onclick="get3()">点击抽取3名幸运观众</button>
		<script>
			function get3(){
				var arr = Array("红红","晃晃","青青","吱吱","端端","格格","丢丢");
				var temp = [];
				//空数组,随机存放3人
				for(var i =0;i<3;i++){
					var num = Math.floor(Math.random()*arr.length);
					//创建一个随机数0-arr的长度
					temp.push(arr[num]);
					//获取到名称放入temp数组最后
					arr.splice(num,1);
					//从第num个删除1个  不重复
				}
				alert(temp);
			}
		</script>
	</body>
</html>

23.冒泡排序

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			var arr = [1,2,12,3,44,31,76,39,8];
			for(var i = arr.length;i>=0;i--){
				for(j=0;j<i+1;j++){
					if(arr[j]>arr[j+1]){
						var temp = arr[j];
						arr[j]=arr[j+1];
						arr[j+1]=temp;
					}
				}
			}
			document.write([arr]);
		</script>
	</body>
</html>

25、降维打击

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			var arr = [1,2,[2,13,24],89,45,[4,5,6,[16,57,[8,88,23]]],66];
			console.log("arr",arr);
			var arr1 = arr.flat(Infinity);
			console.log("arr1",arr1);
			//混合数组被分散开
			
			var arr2 = Array.from(new Set(arr1));
			console.log("arr2",arr2);
			//重复的数字被删除
			
			function compare(a,b){
				if(a>b){
					return 1;
				}else if(a<b){
					return -1;
				}else{
					return 0;
				}
			}
			var arr3 = arr2.sort(compare);
			console.log("arr3",arr3);
		</script>
	</body>
</html>

26、apply和call的用途是什么,有什么区别?
答:①call和apply都属于Function.prototype的一个方法,他是js殷勤内在实现的,因为属于Function.prototype,所以每个Function对象实例(每个方法)都有call,apply属性,既然作为方法的属性,那他们的使用当然是针对方法,这两个方法容易混淆,因为作用一样,只是使用方法不同;
②语法:foo.call(this,arg1,arg2,arg3)==foo.apply(this,arguments)==this.foo(arg1,arg2,arg3);
③相同点:两个方法产生的作用相同;
④不同点:方法传递的参数不同;
27、JavaScript有哪几种方法定义函数?

1.函数声明表达式;
2.function操作符;
3.function构造函数;
4.ES6:arrow function;
28、客户端存储 localStorage 和 sessionStorage的区别?
localStorage 有效期为永久,sessionStorage 有效期为顶层窗口关闭前
同源文档可以读取并修改 localStorage 数据,sessionStorage 只允许同一个窗口下的文档访问,如通过 iframe 引入的同源文档。
Storage 对象通常被当做普通 javascript 对象使用:通过设置属性来存取字符串值,也可以通过setItem(key, value)设置,getItem(key)读取,removeItem(key)删除,clear()删除所有数据,length 表示已存储的数据项数目,key(index)返回对应索引的 key

29、JavaScript有哪些方法定义对象?
1.对象字面量: var obj={}
2.构造函数:var obj = new Object();
3.Object.create():var obj = Object.create(Object.prototype);
30、===运算符判断相等的流程是什么?

1.如果两个值为不同类型,则不相等;
2.如果两个值都是null或者undefined,则相等;
3.如果两个值都是布尔类型true或者都是false,则相等;
4.如果其中有一个是NaN,则不相等;
5.如果都是数值类型且数值相等,则相等,-0等于0;
6.如果他们都是字符串并且在相同位置包含相同的 16 位值,他它们相等;如果在长度或者内容上不等,它们不相等;两个字符串显示结果相同但是编码不同=都认为他们不相等;
7.如果他们指向相同对象、数组、函数,它们相等;如果指向不同对象,他们不相等;
31、==运算符判断相等的流程是怎样的?
如果两个值类型相同,按照=比较方法进行比较
如果类型不同,使用如下规则进行比较
如果其中一个值是 null,另一个是 undefined,它们相等
如果一个值是数字另一个是字符串,将字符串转换为数字进行比较
如果有布尔类型,将true 转换为 1,false 转换为 0,然后用
规则继续比较
如果一个值是对象,另一个是数字或字符串,将对象转换为原始值然后用==规则继续比较
其他所有情况都认为不相等

32、对象到字符串的转换步骤?
如果对象有 toString()方法,javascript 调用它。如果返回一个原始值(primitive value 如:string number boolean),将这个值转换为字符串作为结果
如果对象没有 toString()方法或者返回值不是原始值,javascript 寻找对象的 valueOf()方法,如果存在就调用它,返回结果是原始值则转为字符串作为结果
否则,javascript 不能从 toString()或者 valueOf()获得一个原始值,此时 throws a TypeError

33、对象到数字的转换步骤?
如果对象有valueOf()方法并且返回元素值,javascript将返回值转换为数字作为结果
否则,如果对象有toString()并且返回原始值,javascript将返回结果转换为数字作为结果
否则,throws a TypeError

34、<,>,<=,>=的比较规则?

所有比较运算符都支持任意类型,但是比较只支持数字和字符串,所以需要执行必要的转换然后进行比较,转换规则如下:

1.如果操作数是对象,转换为原始值:如果 valueOf 方法返回原始值,则使用这个值,否则使用 toString 方法的结果,如果转换失败则报错
2.经过必要的对象到原始值的转换后,如果两个操作数都是字符串,按照字母顺序进行比较(他们的 16 位 unicode 值的大小)
3.否则,如果有一个操作数不是字符串,将两个操作数转换为数字进行比较
35、+运算符工作流程?

如果有操作数是对象,转换为原始值;如果有一个操作数是字符串,其他操作数都转换为字符串进行拼接;如果都是数字,则执行加法;
36、函数内部 arguments 变量有哪些特性,有哪些属性,如何将它转换为数组?
arguments 所有函数中都包含的一个局部变量,是一个类数组对象,对应函数调用时的实参。如果函数定义同名参数会在调用时覆盖默认对象
arguments[index]分别对应函数调用时的实参,并且通过 arguments 修改实参时会同时修改实参
arguments.length 为实参的个数(Function.length 表示形参长度)
arguments.callee 为当前正在执行的函数本身,使用这个属性进行递归调用时需注意 this 的变化
arguments.caller 为调用当前函数的函数(已被遗弃)
转换为数组:var args = Array.prototype.slice.call(arguments, 0);
37、用代码写出(今天是星期 x)其中 x 表示当天是星期几,如果当天是星期一,输出应该是"今天是星期一"

var days = ['日','一','二','三','四','五','六'];
var date = new Date();

console.log('今天是星期' + days[date.getDay()]);

38、用代码实现循环延时输出结果0 1 2 3 4;

for (var i = 0; i < 5; ++i) {
  (function (i) {
    setTimeout(function () {
      console.log(i + ' ');
    }, 100);
  }(i));
}

39、鼠标单击 Button1 后将 Button1 移动到 Button2 的后面如何实现?

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>TEst</title>
</head>
<body>

<div>
   <input type="button" id ="button1" value="1" />
   <input type="button" id ="button2" value="2" />
</div>

<script type="text/javascript">
    var btn1 = document.getElementById('button1');
    var btn2 = document.getElementById('button2');

    addListener(btn1, 'click', function (event) {
        btn1.parentNode.insertBefore(btn2, btn1);
    });

    function addListener(elem, type, handler) {
        if (elem.addEventListener) {
            elem.addEventListener(type, handler, false);
            return handler;
        } else if (elem.attachEvent) {
            function wrapper() {
                var event = window.event;
                event.target = event.srcElement;
                handler.call(elem, event);
            }
            elem.attachEvent('on' + type, wrapper);
            return wrapper;
        }
    }

</script>
</body>
</html>

40、网页中实现一个计算当年还剩多少时间的倒数计时程序,要求网页上实时动态显示"×× 年还剩 ×× 天 ×× 时 ×× 分 ×× 秒"

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>TEst</title>
</head>
<body>

    <span id="target"></span>


<script type="text/javascript">
    // 为了简化。每月默认30天
    function getTimeString() {
        var start = new Date();
        var end = new Date(start.getFullYear() + 1, 0, 1);
        var elapse = Math.floor((end - start) / 1000);

        var seconds = elapse % 60 ;
        var minutes = Math.floor(elapse / 60) % 60;
        var hours = Math.floor(elapse / (60 * 60)) % 24;
        var days = Math.floor(elapse / (60 * 60 * 24)) % 30;
        var months = Math.floor(elapse / (60 * 60 * 24 * 30)) % 12;
        var years = Math.floor(elapse / (60 * 60 * 24 * 30 * 12));

        return start.getFullYear() + '年还剩' + years + '年' + months + '月' + days + '日'
            + hours + '小时' + minutes + '分' + seconds + '秒';
    }

    function domText(elem, text) {
        if (text == undefined) {

            if (elem.textContent) {
                return elem.textContent;
            } else if (elem.innerText) {
                return elem.innerText;
            }
        } else {
            if (elem.textContent) {
                elem.textContent = text;
            } else if (elem.innerText) {
                elem.innerText = text;
            } else {
                elem.innerHTML = text;
            }
        }
    }

    var target = document.getElementById('target');

    setInterval(function () {
        domText(target, getTimeString());
    }, 1000)
</script>

</body>
</html>

41、完成一个函数,接受数组作为参数,数组元素为整数或者数组,数组元素包含整数或数组,函数返回扁平化后的数组,如:[1, [2, [ [3, 4], 5], 6]] => [1, 2, 3, 4, 5, 6]

var data =  [1, [2, [ [3, 4], 5], 6]];

    function flat(data, result) {
        var i, d, len;
        for (i = 0, len = data.length; i < len; ++i) {
            d = data[i];
            if (typeof d === 'number') {
                result.push(d);
            } else {
                flat(d, result);
            }
        }
    }

    var result = [];
    flat(data, result);
    console.log(result);

42、现有一个字符串 richText,是一段富文本,需要显示在页面上.有个要求,需要给其中只包含一个 img 元素的 p 标签增加一个叫 pic 的 class.请编写代码实现.

function richText(text) {
    var div = document.createElement('div');
    div.innerHTML = text;
    var p = div.getElementsByTagName('p');
    var i, len;

    for (i = 0, len = p.length; i < len; ++i) {
        if (p[i].getElementsByTagName('img').length === 1) {
            p[i].classList.add('pic');
        }
    }

    return div.innerHTML;
}

}

43、有一个大数组,var a = [‘1’, ‘2’, ‘3’, …];a 的长度是 100,内容填充随机整数的字符串.请先构造此数组 a,然后设计一个算法将其内容去重

/**
    * 数组去重
    **/
    function normalize(arr) {
        if (arr && Array.isArray(arr)) {
            var i, len, map = {};
            for (i = arr.length; i >= 0; --i) {
                if (arr[i] in map) {
                    arr.splice(i, 1);
                } else {
                    map[arr[i]] = true;
                }
            }
        }
        return arr;
    }

    /**
    * 用100个随机整数对应的字符串填充数组。
    **/
    function fillArray(arr, start, end) {
        start = start == undefined ? 1 : start;
        end = end == undefined ?  100 : end;

        if (end <= start) {
            end = start + 100;
        }

        var width = end - start;
        var i;
        for (i = 100; i >= 1; --i) {
            arr.push('' + (Math.floor(Math.random() * width) + start));
        }
        return arr;
    }

    var input = [];
    fillArray(input, 1, 100);
    input.sort(function (a, b) {
        return a - b;
    });
    console.log(input);

    normalize(input);
    console.log(input);

44、请简单写出匹配email地址的正则表达式。

var reg = /^\w+@\w+.[a-zA-Z]{2,3}(.a[a-zA-Z]{2,3})?$/;

你可能感兴趣的:(JavaScript面试习题练习)