前端面试题及答案.全全全!!!---js

HTML——CSS——JS——es6——Vue——微信小程序-----------服务器----------node

JS面试题

1.基本数据类型有哪几种?

undefined,null,boolean,string,number,Symbol(es6)

2.引用数据类型有哪些?

Object,Array

3.JavaScript的typeof返回的数据类型?

string number array object function Boolean undefined

4.强制类型转换

Number(参数)把任何类型转换成数值类型

parseInt(参数1,参数2)将字符串转换成整数

parseFloat()将字符串转换成浮点数字

string(参数):可以将任何类型转换成字符串

Boolean()可以将任何类型的值转换成布尔值

5.隐式类型转换

== ===

扩展:通过==比较两边的值是否相等的结果?
1==’1’
null==undefined

6.逻辑运算符:与,或,非

|| : 只要其中有一个为true,整体结果是true; 
&& : 只要有一个是false,整体结果是false; 
!:取反 (比较:转布尔,在取反)

7.null和undefined是否相等?null和undefined的区别?

    console.log(null==undefined)//true
    console.log(null===undefined)//false

  null: object类型,代表“空值”,代表一个空对象指针,(表示现在没有,但是以后可能会有)

undefined: undefined类型(现在没有,以后也不能有)

8.JS四种检测

1、typeOf:只能检测基本数据类型 
2、instanceOf:检测当前实例是否属于某个类的方法 
3、检测当前实例的构造函数 
4、Object.prototype.toString.call([]); 最准确的方式;

区别是什么

 

9.continue和break的区别

continue; 结束本轮循环; 
break: 结束整个循环;

10.for…in..和for…of..的区别?

for in 遍历循环对象

  • 同时for in也可以遍历数组,但是会出现以下问题 
    1、index索引为字符串型数字,不能直接进行几何运算 
    2、遍历顺序有可能不是按照实际数组的内部顺序 
    3、使用for in会遍历数组所有的可枚举属性,包括原型。

for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。

for of 遍历循环数组

  • for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name

11.、什么是函数的封装?

把实现相同功能的代码放到一个函数体中,当想实现这个功能时,直接执行这个函数即可;减少了的冗余;高内聚,低耦合

12.堆栈内存

当浏览器加载页面时,会形成两个虚拟的内存;一个栈内存,堆内存;

栈内存:

  • 1) 提供代码的运行环境;
  • 2) 存储基本数据类型;

堆内存: 存储引用数据类型

13.函数的执行过程

  • 1.首先会形成一个私有的作用域
  • 2.形参赋值
  • 3.变量提升
  • 4.代码从上到下运行;
  • 5.作用域的销毁; 
    在函数执行时,函数体中可以找到函数外面的变量;但是函数外面不能访问里面的变量;

14.闭包

当函数执行时,首先会形成一个私有的作用域,这个私有作用域保护了里面的私有变量不受外界的干扰;这种机制--> "闭包";

15.Number的方法

isNaN : 强制转换成number,在判断 
Number :将其他数据类型的值强制转换成number类型; 
parseInt :经常用于字符串提取数字的方法; 
parseFloat:和parseInt 用法一样;区别是多识别一位小数点 
toFixed : 保留小数点位数的方法;返回值是一个字符串;

16.字符串的方法(13个)

toUpperCase : 把小写字母转成大写 
toLowerCase 把大写转小写 
charAt : 通过索引获取字符 
charCodeAt : 通过索引获取对应字符的Unicode编码; 
substr : 截取 substr(m,n) 从索引m开始,截取n个字符; 
substring: substring(m,n) :从索引m开始,截取到索引n,不包含n; (不支持负数) 
slice(m,n): substring; 从索引m开始,截取到索引n,不包含n (支持负数) 
indexOf : 检测字符在字符串中第一次出现的索引位置; 
lastIndexOf : 检测字符在字符串中最后一次出现的索引位置; 
split: 把字符串按照特定的字符分隔数组中的每一项; 
replace:替换;原有字符串不变;用新字符替换旧的字符 
concat : 拼接 

17.字符串的运算

- * /: 会先把字符串转换成数字,然后再进行计算

  1. 任何数字和NaN 计算,结果都是NaN;
  2. 任何数字和undefined运算,得到也是NaN;

+: 字符串拼接;

  • [] : 空数组在进行拼接时,会默认调用toString转换成空字符串;然后拼接;

18.、获取元素的方法

document.getElementById:通过ID名来获取元素 
document.getElementsByTagName: 通过标签名来获取元素 
document.getElementsByClassName(); 类数组集合; 
document.getElementsByName;通过name属性来获取元素; 
document.documentElement 获取当前的html 
body :获取页面的body元素; 
document.querySelector();如果是id名加#,如果是class名加. 
document.querySelectorAll();获取所有的元素

19.split() join() 的区别

split():把一个字符串分割成字符串数组,并返回

“hello".split("")   // ["h", "e", "l", "l", "o"]

join():把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的,并返回

在本例中,我们将创建一个数组,然后把它的所有元素放入一个字符串:

<script type="text/javascript">

var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"

console.log(arr.join())

</script>
输出:

George,John,Thomas

20.数组的方法

push()尾部添加,返回 数组长度(向数组末尾新增一项;可以传多个)

var arr = ["Lily","lucy","Tom"];
var count = arr.push("Jack","Sean");
console.log(count); // 5
console.log(arr); // ["Lily", "lucy", "Tom", "Jack", "Sean"]

pop()尾部删除,返回 被删除的元素(删除数组的最后一项;不需要传参数;)

var item = arr.pop();
console.log(item); // Sean
console.log(arr); // ["Lily", "lucy", "Tom", "Jack"]

unshift()头部添加 ,返回 数组长度

var arr = ["Lily","lucy","Tom"];
var count = arr.unshift("Jack","Sean");
console.log(count); // 5
console.log(arr); //["Jack", "Sean", "Lily", "lucy", "Tom"]

shift()头部删除,返回被删除的元素

var item = arr.shift();
console.log(item); // Jack
console.log(arr); // ["Sean", "Lily", "lucy", "Tom"]

sort():按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。

在排序时,sort()方法会调用每个数组项的 toString()转型方法,然后比较得到的字符串,以确定如何排序。即使数组中的每一项都是数值, sort()方法比较的也是字符串,因此会出现以下的这种情况:

var arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](元数组被改变)

为了解决上述问题,sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:

function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]

如果需要通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可:

function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]

reverse():反转数组项的顺序

var arr = [13, 24, 51, 3];
console.log(arr.reverse()); //[3, 51, 24, 13]
console.log(arr); //[3, 51, 24, 13](原数组改变)

concat():数组的拼接 。将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。

var arr = [1,3,5,7];
var arrCopy = arr.concat(9,[11,13]);
console.log(arrCopy); //[1, 3, 5, 7, 9, 11, 13]
console.log(arr); // [1, 3, 5, 7](原数组未被修改)

slice():数组的截取 

slice(m,n): 从数组索引m开始,截取到索引n,但是不包含n;[前包后不包] 
slice(m) : 从索引m开始,截取到末尾; 
slice():数组的克隆 slice(0); 
原有数组不发生改变;

返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。

var arr = [1,3,5,7,9,11];
var arrCopy = arr.slice(1);
var arrCopy2 = arr.slice(1,4);
var arrCopy3 = arr.slice(1,-2);
var arrCopy4 = arr.slice(-4,-1);
console.log(arr); //[1, 3, 5, 7, 9, 11](原数组没变)
console.log(arrCopy); //[3, 5, 7, 9, 11]
console.log(arrCopy2); //[3, 5, 7]
console.log(arrCopy3); //[3, 5, 7]
console.log(arrCopy4); //[5, 7, 9]

splice:删除数组中的某几项 
splice(m,n): 从索引开始,删除n个 
splice(m) : 从索引m开始删除到末尾; 
splice(0): 
splice(m,x,n);替换从索引m开始,删除x个,用n替换; 
原有数组发生改变

indexOf()和 lastIndexOf()

indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。
这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回-1。在比较第一个参数与数组中的每一项时,会使用全等操作符。

var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.lastIndexOf(5)); //5
console.log(arr.indexOf(5,2)); //2
console.log(arr.lastIndexOf(5,4)); //2
console.log(arr.indexOf("5")); //-1

forEach()对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。

var arr = [1, 2, 3, 4, 5];
arr.forEach(function(x, index, a){
console.log(x + '|' + index + '|' + (a === arr));
});
// 输出为:
// 1|0|true
// 2|1|true
// 3|2|true
// 4|3|true
// 5|4|true

map()指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(item){
return item*item;
});
console.log(arr2); //[1, 4, 9, 16, 25]

filter()过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
return index % 3 === 0 || x >= 8;
}); 
console.log(arr2); //[1, 4, 7, 8, 9, 10]

every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
return x < 10;
}); 
console.log(arr2); //true
var arr3 = arr.every(function(x) {
return x < 3;
}); 
console.log(arr3); // false

some()

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
return x < 3;
}); 
console.log(arr2); //true
var arr3 = arr.some(function(x) {
return x < 1;
}); 
console.log(arr3); // false

21.事件绑定和普通事件有什么区别

普通事件(onclick):直接触发事件,同一时间只能指向唯一对象,所以会被覆盖掉

var btn = document.getElementById("btn")
btn.onclick = function(){
    alter("你好111")
}
btn.onclick = function(){
     alter("你好222")
}

输出的结果只会有<你好222>,一个click处理器在同一时间只能指向唯一的对象。所以就算一个对象绑定了多次,其结果只会出现最后的一次绑定的对象。

事件绑定(addEventListener):事件绑定就是对于一个可以绑定的事件对象,进行多次绑定事件都能运行

var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
	alert("你好111");
},false);
btn.addEventListener("click",function(){
	alert("你好222");
},false);

运行结果会依次弹出你好111,你好222的弹出框。

区别:

addEventListener对任何DOM都是有效的,而onclick仅限于HTML.

addEventListener可以控制listener的触发阶段,(捕获/冒泡)。对于多个相同的事件处理器,不会重复触发,不需要手动使用removeEventListener清除。

22.DOM四种类型的节点

TYPE nodeType nodeName nodeValue
元素节点 1 大写的标签名 null
文本节点 3 text 文本内容
注释节点 8 comment 注释内容
document 9 document null

 

空格和换行都是文本节点;

23.DOM节点的属性

childNodes : 获取当前元素所有的子节点; 
children : 获取当前元素的子元素节点; 
firstChild : 获取第一子节点; 
lastChild :获取最后一个子节点 
previousSibling : 获取上一个哥哥节点 
nextSibling : 获取下一个弟弟节点 
parentNode: 获取当前元素的父亲节点;

24.Math的方法

Math.abs(): 取绝对值; 
Math.floor() : 向下取整 
Math.ceil() : 向上取整 
Math.max() : 取最大值 
Math.min() : 取一组数的最小值 
Math.random() 取随机数,取值范围[0,1) 
Math.round(): 四舍五入取整 
取m-n之间的随机整数:Math.round(Math.random()*(n-m)+m) 
Math.pow() : 取幂次方 
Math.sqrt() : 开平方;

25.Date的实例

console.log(typeof new Date());

// "object"

console.log(new Date());

// 获取本机的系统时间;

var time = new Date();

console.log(time.getFullYear());

// 获取时间年;

console.log(time.getMonth())

// 获取时间月 取值范围【0-11】

console.log(time.getDate());

// 获取时间日【1-31】

console.log(time.getDay());

// 获取星期几;【0-6】 星期日是0;

console.log(time.getHours())

// 获取小时数 【0-23】

console.log(time.getMinutes());

// 获取分钟数 【0-59】

console.log(time.getSeconds());

// 获取时间秒【0-59】 console.log(time.getMilliseconds());

// 获取毫秒数【0-999】

console.log(time.getTime());

// 当前时间距离1970-1-1日早上八点的毫秒数;

console.log(Date.now());

26.数组的去重

var ary = [12,8,88,12,99,88,66,77,66];
var a = [12,8,88,99,66,77];
var newAry = [];
forEach map ;

1、indexOf: 判断当前项在数组中是否存在,不存在返回-1;

for(var i=0;i<ary.length;i++){
var cur = ary[i];
// 判断当前项在新数组中是否存在,不存在返回-1;
if(newAry.indexOf(cur)===-1){
newAry.push(cur);
}
}
console.log(newAry);//[12, 8, 88, 99, 66, 77]

2、对象的属性名不能重复;

var obj = {1:10,1:16};
console.log(obj);
var ary = [12,8,88,12,99,88,66,77,12];
var obj = {};// {12:12,8:8,88:88}
for(var i=0;i<ary.length;i++){
var cur = ary[i];// 12
if(obj[cur]===cur){
ary.splice(i,1); 缺点: 数组塌陷;删除这一项后面的所有项的索引都要进行重新计算;
ary[i] = ary[ary.length-1];// 把数组最后一项赋值给当前项
ary.length--;// 删除最后一项;
i--;
continue;// 结束本轮循环
}
obj[cur] = cur;// 新增键值对;当属性名不存在时,执行此处代码
}
console.log(obj);//
console.log(ary);

3.转换成数组

var ary = [12,8,88,12,99,88,66,77,12];
var obj = {};// {12:12,8:8,88:88}
for(var i=0;i<ary.length;i++){
var cur = ary[i];// 12
obj[cur] = cur;// 新增键值对;当属性名不存在时,执行此处代码
}
//转换成数组
var newAry = [];
for(var key in obj){
newAry.push(obj[key])
}
console.log(newAry);

27.函数的递归

递归: 针对的是函数; 是JS中一种重要的思想; 
函数: 分为定义和执行 
函数递归: 在函数体内部,调用函数自己本身,让其执行;这就是递归;

function sum(num) {
if(num === 0){
return num;
}
if(num%3===0){
return num + sum(num-1);
}
if(num%3!==0){
return sum(num-1);
}
// return sum(99)
// return 99 + sum(98)
// return 99 + sum(97)
// return 99 + sum(96)
// return 99 + 96 + sum(95)....
// return 99 + 96 +... + 3 + sum(2)
// return 99 + 96 +... + 3 + sum(1)
// return 99 + 96 +... + 3 + 0
}
console.log(sum(100));
console.log(sum(200));

28.求1-100之间是3倍数的和(% : 取模;取余数)

var total = 0;
for(var i=0;i<100;i++){
if(i%3===0){
total += i;
}
}

29.数组的插入排序

var ary = [12,88,67,98,56,35,45,26,1];
//5 6 7 8 10
//得到的新数组是排好序
//插入排序原理:去原有数组中去取每一项,然后和新数组中的成员进行比较,从新数组后面开始,一一向前比较,比新数组项小,继续和前一项比较,直到当前项比数组中一项值大时,把它放到这一项的后面;
var newAry = [];
newAry.push(ary[0]);
for(var i=1;i<ary.length;i++){
var cur = ary[i];
for(var j=newAry.length-1;j>=0;j--){
if(cur<newAry[j]){// 如果数组中拿到的这一项比新数组中j的这一项小;那么继续j--;和上一个成员进行比较;
if(j===0){
newAry.unshift(cur);
break;// 只会中止当前的小循环
}
}else{
// cur<newAry[j]的情况,把当前项放到新数组这一项的后面;
newAry.splice(j+1,0,cur);
break;
}
}
}
// 从前向后
console.log(newAry);
var ary = [12,88,67,98,56,35,45,26,1];
var mAry = [12,67,88];
mAry.push(ary[0]);
for(var i=1;i<ary.length;i++){
var cur = ary[i];
for(var j = mAry.length-1;j>=0;j--){
if(cur<mAry[j]){
if(j===0){
mAry.unshift(cur);
break;
}
}else{
mAry.splice(j+1,0,cur);
break;
}
}
}

30.数组的冒泡排序

var ary = [12,32,56,67,88,99,101];
// 1. sort
/*ary.sort(function (a,b) {
return a-b;// 从小到大
});*/
// 实现从小到大
// 让相邻两项进行比较,如果前面一项比后面一项大,那么让这两项互换位置;如果前比后面一项小,那么不换位置;每循环一整轮,把数组的最大值放到数组的最后面;有多少项,就执行多少次这样的循环;
for(var j = 0;j<ary.length;j++){
// 当外面的循环循环一次;
var flag = true;// 标识的作用
for(var i=0;i<ary.length-1-j;i++){
// 里面整个循环完一次,实现将最大值放到最后;
if(ary[i]>ary[i+1]){//前面一项比后面大
// 借助第三方变量
//如果能进来,说明数组没有排好顺序;如果进不来,说明数组已经是排好的
var temp = ary[i];
ary[i] = ary[i+1];
ary[i+1] = temp;
flag = false;
}
}
if(flag){
break;
}
}
console.log(ary);

31.数组的快速排序(快速排序快速排序的原理: 首先取原有数组中的中间项;接下来循环原有的数组每一项,和中间项进行比较,如果比中间项的小的放在左边的数组中,比中间项大的放在右边的数组中;然后再对左边和右边数组进行刚才的操作;最后把所有的小数组和中间项串在一起就是排好的数组;)

var ary = [12,8,89,78,76,56,25,35];
function quickSort(ary) {
console.log(ary);
// 当数组的长度小于等于1;直接return当前的数组;
if(ary.length<=1){
return ary;
}
//获取
var middleIndex = Math.floor(ary.length/2);
//删除数组中中间项;并且获取中间项的值
var middleVal = ary.splice(middleIndex,1)[0];
console.log(middleVal);
var left = [];
var right = [];
for(var i=0;i<ary.length;i++){
var cur = ary[i];
//比中间项的小的放中间项的左边的数组,比中间项大的放中间项的右边的数组
if(cur<middleVal){
left.push(cur);
}else{
right.push(cur);
}
}
//对中间左右两边的数组进行重新这样的操作
return quickSort(left).concat(middleVal,quickSort(right))
}
var newAry = quickSort(ary);
console.log(newAry);

32.随机验证码

var code = document.getElementById("code");
function getCode() {
// 准备一个62个字符串;
// 产生随机数;随机数可以作为字符的索引;
// 随机索引范围【0-61】
var str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 随机数;
var i =0;
var newStr = "";
while(i<4){
var num = Math.round(Math.random()*(61-0)+0);
newStr+=str[num];
i++;
}
code.innerHTML = newStr;
}
getCode();
// 把函数的空间地址赋值给code的onclick属性;
code.onclick = getCode;

33.设置定时器

1) setTimeout() 
2) setInterval()

34.清除定时器

1) clearTimeout() 
2) setInterval()

35.call和apply的区别

考点:call和apply的用法

call和apply相同点:改变函数中this的指向

不同点:函数参数的传递形式
call将函数参数依次传入
apply将函数参数用一个数组的形式传入

无参数调用:

function fn(){
    alert(this.name);
}
var p1={name:1};
fn.call(p1);
fn.apply(p1);

有参数调用:

function fn2(name,age){
    this.name=name;
    this.age=age;
}
var p1={};
fn2.call(p1,"张三",20);
fn2.apply(p1,["张三",20]);

36.JavaScript this、闭包、作用域

this:指向调用上下文

作用域:定义一个函数就开辟了一个局部作用域,整个js执行环境有一个全局作用域

闭包:一个函数可以访问其他函数中的变量(闭包是一个受保护的变量空间)

var f=(function fn(){
    var name=1;
    return function(){
        name++;
        console.log(name);
    }
})();

37.闭包是什么,有什么特性,对页面有什么影响

闭包就是能够读取其他函数内部变量的函数。
闭包的缺点:
1 更多的内存消耗
2 性能问题(跨作用域访问)
3滥用闭包函数会造成内存泄露,因为闭包中引用到的包裹函数中定义的变量都永远不会被释放,所以我们应该在必要的时候,及时释放这个闭包函数

闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。
可以把闭包简单理解成 “定义在一个函数内部的函数”,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包有如下特性:
a. JavaScript允许你使用在当前函数以外定义的变量
b. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量
c. 闭包可以更新外部变量的值
d. 用闭包模拟私有方法
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题
38.”==”和“===”的不同

==:会自动转换类型
===:先判断左右两边的数据类型,如果数据类型不一致,直接返回false
之后才会进行两边值的判断

1==”1”
null==undefined;//==true

39.javascript的同源策略

一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合
http,ftp:协议
关键词解释:
主机名:localhost、www.baidu.com
协议:http https ftp
端口:一个网站对应着一个端口, http协议的默认端口:80
https协议的默认端口是8083
同源策略带来的麻烦:ajax在不同域名下的请求无法实现,
如果说想要请求其他来源的js文件,或者json数据,那么可以通过jsonp来解决
跨域解决方式一
跨域解决方式二
40.已知ID的Input输入框,希望获取这个输入框的输入值,怎么做?(不使用第三方框架)

document.getElementById(“ID”).value

41.看下列代码,输出什么?解释原因。

    var a = null;
alert(typeof a); //object

42.看下列代码,输出什么?解释原因。

var undefined;//此时undefined这个变量的值是undefined
undefined == null; // true
1 == true;   // true
此时会把布尔类型的值转换为数字类型 true=1 false=0
2 == true;   // false
0 == false;  // true
0 == '';     // true
NaN == NaN;  // false isNaN
[] == false; // true   解释:会把[]和false都通过Number()转换为数字类型
[] == ![];   // true   解释:![]:false
[]==[];//false

43.看下列代码会有什么样的输出?

var foo = "11"+2-"1";  
console.log(foo);//112-1=111
console.log(typeof foo);//”number”

考点:
1、数字和字符串都可以用加法运算符,数字和字符串相加,结果就是一个字符串
2、但是减法运算符只能用于两个数字之间,想要执行减法运算,必须把两边数字都变成数字类型的
答案:”111”、”number”

44.看代码给答案。

var a = new Object();
a.value = 1;
b = a; //b.value=1
b.value = 2;//b.value=2;a.value=2,因为a和b指向同一块引用类型的值
alert(a.value);

答案:2

45.已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],alert出”This is Baidu Campus”。

考点:数组的join方法的使用
答案:alert(stringArray.join(“ ”))

46.已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”。

    function combo(msg){
    var arr=msg.split("-");//[get,element,by,id]
    for(var i=1;i<arr.length;i++){
        arr[i]=arr[i].[0].toUpperCase()+arr[i].substring(1);//Element
    }
    msg=arr.join("");//msg=” getElementById”
    return msg;
}

47.var numberArray = [3,6,2,4,1,5];

1)实现对该数组的倒排,输出[5,1,4,2,6,3]

function reverseArray(arr){
    var result=[];
    //方法1:
    /*for (var i = arr.length - 1; i >= 0; i--) {
        result.push(arr[i]);
    }*/
    //方法2:
    for (var i = 0, len = arr.length; i < len; i++) {
        result.unshift(arr[i]);
    }
    return result;
}

2)实现对该数组的降序排列,输出[6,5,4,3,2,1]

function sortDesc(arr) {
    for (var i = 0, len = arr.length; i < len; i++) {
        for (var j = i + 1, len2 = arr.length; j < len2; j++) {
            //>就是降序 <就是升序
            if (arr[j] > arr[i]) {
                var temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }
        }
    }
    return arr;
}

48.输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26

考点:日期对象Date相关API的使用

var d = new Date();

// 获取年,getFullYear()返回4位的数字
var year = d.getFullYear();
// 获取月,月份比较特殊,0是1月,11是12月
var month = d.getMonth() + 1;
// 变成两位
month = month < 10 ? ‘0’ + month : month;
// 获取日
var day = d.getDate();
day = day < 10 ? ‘0’ + day : day;
alert(year + ‘-’ + month + ‘-’ + day);
49.foo = foo||bar ,这行代码是什么意思?为什么要这样写?

var foo;
if(foo){
    foo=foo;
}else{
    foo=bar;
}

答案:常用于函数参数的空判断
短路表达式:作为”&&”和”||”操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。
考点:if条件的真假判定
记住以下是false的情况:空字符串、false、undefined、null、0
50.看下列代码,将会输出什么?

考点:1、变量作用域 2、变量声明提升

var foo = 1;
function f(){
    console.log(foo);
    var foo = 2;
    console.log(foo);
}
f();

输出undefined 和 2。

51.用js实现随机选取10–100之间的10个数字,存入一个数组,并排序。

var iArray = []; 
function getRandom(istart, iend){
        var iChoice = iend - istart +1;
        return Math.floor(Math.random() * iChoice+ istart);
}
Math.random()就是获取0-1之间的随机数(永远获取不到1)
for(var i=0; i<10; i++){
var result= getRandom(10,100);
        iArray.push(result);
}
iArray.sort();

52.把两个数组合并,并删除第二个元素。

考点:1、数组的concat、splice用法
splice() 方法删除数组的元素,或者向数组中添加元素,然后返回被删除的项目。
参数1:从何处开始删除数组的元素(使用负数则从数组的末尾开始)
参数2:要删除的元素个数(如果是0,就代表不删除)
参数3,4,5。。。:要添加的元素
 

var array1 = ['a','b','c'];

var bArray = [‘d’,’e’,’f’];
var cArray = array1.concat(bArray);
cArray.splice(1,1);

53.写一个function,清除字符串前后的空格。(兼容所有浏览器)

使用自带接口trim(),考虑兼容性(IE9以下浏览器不支持):
考点:1、原型扩展 2、正则表达式 3、字符串的replace方法

if(typeof String.prototype.trim !=”function”){
String.prototype.trim=function(){
return this.replace(/^\s+|\s+$/g,”“);
}
}
var str=” hello “;

54.Javascript中, 以下哪条语句一定会产生运行错误? 答案( BC )

A、var _变量=NaN;
B、var 0bj = [];
C、var obj = //;
D、var obj = {};
//正确答案:BC

55.简述创建函数的几种方式

第一种(函数声明):

function sum1(num1,num2){
   return num1+num2;
}

第二种(函数表达式):

var sum2 = function(num1,num2){
   return num1+num2;
}

匿名函数:没有函数名称,无法通过函数名称调用

function(){}:只能自己执行自己

第三种(Function构造函数方式):

var sum3 = new Function("num1","num2","return num1+num2");

56.Javascript创建对象的几种方式?

构造函数方式,原型模式,混合构造函数原型模式,工厂方式,动态原型方式

混合构造函数+原型模式:

function Robot(name){
    this.name=name;
}
Robot.prototype.say=function(){
    alert("大家好,我叫"+this.name);
};
var alphaGo=new Robot("阿尔法狗");
alphaGo.say();

工厂方式:

function create(name,age){
    var o={};
    o.name=name;
    o.age=age;
    return o;
}
var p1=create("张三",20);

动态原型方式:

function Person(name,work){
    this.name=name;
    if(work){
        Person.prototype.doWork=function(){
            alert("我正在从事"+work+"的工作");
        }
    }
}
var p1=new Person("姚明");
var p2=new Person("喵喵","程序猿鼓励师");

57.DOM操作——怎样添加、移除、移动、复制、创建和查找节点。

创建新节点
createDocumentFragment() // 创建一个DOM片段
createElement() // 创建一个具体的元素
createTextNode() // 创建一个文本节点
添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() // 在已有的子节点前插入一个新的子节点
查找
getElementsByTagName() // 通过标签名称
getElementsByName() // 通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
getElementById() // 通过元素Id,唯一性
58.js延迟加载的方式有哪些?

  1. defer和async
    defer:当文档加载完成之后执行
    async:异步执行脚本
  2. 动态创建DOM方式
    创建script,插入到DOM中,加载完毕后callBack)

59.documen.write和 innerHTML 的区别?

document.write 指定位置输出
dom.innerHTML 可以重绘指定元素的内容
document.write和innerHTML的区别

60.哪些操作会造成内存泄漏?

内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
1. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
2. 闭包
3. 控制台日志
内存泄漏的几种情况
61.解释jsonp的原理,以及为什么不是真正的ajax

动态创建script标签,回调函数
Ajax是页面无刷新请求数据操作

62.将数字 12345678 转化成 RMB形式 如: 12,345,678

//思路:先将数字转为字符, str= str + ” ;
//利用反转函数,每三位字符加一个 ‘,’最后一位不加; re()是自定义的反转函数,最后再反转回去!

for(var i = 1; i <= re(str).length; i++){
    tmp += re(str)[i - 1];
    if(i % 3 == 0 && i != re(str).length){
        tmp += ',';
    }
}

63.请解释变量声明提升 (hoisting)

在JavaScript代码运行之前其实是有一个编译阶段的。编译之后才是从上到下,一行一行解释执行。变量提升就发生在编译阶段,它把变量和函数的声明提升至作用域的顶端。(编译阶段的工作之一就是将变量与其作用域进行关联)。

变量提升需要注意:

在js中用var ,function声明的变量都将被提到函数的最顶部。(但是不会初始化)
函数声明的优先级大于变量声明的优先级(function > var)
在函数内部变量提升的优先级会小于函数参数(函数参数 > 函数内部变量提升)
对于函数声明来说,如果定义了相同的函数变量声明,后定义的声明会覆盖掉先前的声明

64.什么是三元表达式 (Ternary expression)?“三元 (Ternary)” 表示什么意思?

一个运算符如果有一个操作数,为一元运算符,两个为二元,三个为三元运算符,三元表达式则为一个三元运算表达式!

65.什么是 “use strict”; ? 使用它的好处和坏处分别是什么?

ECMAScript5中引入的严格模式,通过让JavaScript运行环境对一些开发过程中最常见和不易发现的错误做出和当前不同的处理,来让开发者拥有一个”更好”的JavaScript语言。

好处:

消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的Javascript做好铺垫。
好处具体体现:

去除WITH关键词
防止意外为全局变量赋值
函数中的THIS不再默认指向全局
防止重名
安全的 EVAL()
对只读属性修改时抛出异常
坏处:同样的代码,在“严格模式”中,可能会有不一样的运行结果;一些在“正常模式”下可以运行的语句,在“严格模式”下将不能运行

总结:启用JavaScript严格模式,它能帮你发现代码中未曾注意到的错误。不要在全局环境中启用,但你能尽量多的使用IIFE(立即执行函数表达式)来把严格模式作用到多个函数范围内。一开始,你会遇到之前未曾碰到过的错误提示,这是正常的。当启用严格模式后,请确保在支持的浏览器中做了测试,以发现新的潜在问题。一定不要仅仅在代码中添加一行”use strict”就假定余下的代码能正常工作。

66.你使用哪些工具和技术来调试 JavaScript 代码?

alert
console.log
Debugger断点(具体的说就是通过在代码中添加”debugger;”语句,当代码执行到该语句的时候就会自动断点。)
67.请解释同步 (synchronous) 和异步 (asynchronous) 函数的区别。

同步式:当计算机调度线程进行I/O操作命令后,由于文件的读写或者网络通信需要较长的操作时间,操作系统为了充分利用cpu,此时会暂停到当前的I/O线程对CPU的控制(故又称同步式为阻塞式I/O),把cup资源然给其他的线程资源,当I/O线程完成了操作时,此时操作系统会恢复此时的I/O线程,从而当前I/O线程重新获得了cup的的控制权,继续完成其他操作。

异步式:异步式IO又称非阻塞式I/O,异步式与同步式不同的是,当线程进行IO操作时,操作系统并不是暂停当前的线程操作,而是执行完I/O指令后,操作系统继续让当前线程执行下一条指令,当I/O操作完成后,会通过事件(event)通知I/O线程,而线程在接收到通知后,会处理响应事件。

68.const let var 区别?

var声明的变量会挂载在window上,而let和const声明的变量不会
var声明变量存在变量提升,let和const不存在变量提升
let和const声明形成块作用域
同一作用域下let和const不能声明同名变量,而var可以
let和const有着暂存死区(即从作用域开始到变量申明的这一部分,不能使用该变量,否则会报错。)
const(一旦声明必须赋值,不能使用null占位)

69.字符串的截取两个方法(subString subStr)的区别?

stringObject.substr(start,length):在字符串中抽取从 start 下标开始的指定数目的字符
stringObject.substring(start,stop): 用于提取字符串中介于两个指定下标之间的字符

70.怎么检测数组?

instanceof
isArray
Object.toString
注意: typeof 数组和Null 返回的是'Object'

71.如果某一个接口很缓慢,用户离开这个页面该怎么处理?

72.对象的深拷贝?ES6、ES5

浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

深拷贝对象(不讨论数组的情况):

循环遍历对象的属性赋值
ES6的Object.assign: (用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),并返回合并后的target)
ES6扩展运算符:扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
JSON.parse(JSON.stringify(obj)): 上面三种方法不能拷贝所有层级,该方法可以拷贝对象所有层级
valueOf 如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单地返回对象本身,而不是返回一个原始值
手动些递归(-_-!)

参考:https://www.cnblogs.com/pengh...

73.跨域? 

同源指的是:URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
同源策略:浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性(但是允许当前源执行其他源的脚本)

前端跨域实现方式:

JSONP:<script> 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。
修改document.domain: 浏览器脚本修改document.domain。域名只允许往上升,例如a.git.com到git.com,这样脚本就可以访问git.com上的资源了。还有种用法是假设浏览器访问了a.git.com和b.git.com,如果它们的脚本都把域名设为git.com,那么浏览器本地的资源可以共享。
window.postMessage:Html5的新方法,两个域下的脚本可以跨window通信。
利用表单:浏览器里不禁止表单跨域,所以可以用Javascript + iframe + 表单实现跨域调用
服务端跨域实现方式:

反向代理服务器: 将你的服务器配置成 需要跨域获取的资源的 反向代理服务器。也就是说,将其他域名的资源映射到你自己的域名之下,这样浏览器就认为他们是同源的。
Cross-Origin Resource Sharing: 是 W3C 推出的一种跨站资源获取的机制。服务器 在响应头中设置相应的选项,浏览器如果支持这种方法的话就会将这种跨站资源请求视为合法,进而获取资源。

74.new 对象时发生了什么?

初始化一个空对象
绑定 this
执行构造函数
返回这个对象(不需要return来返回)

75.cookie 不设置过期时间,默认过期时间是多少?

关闭浏览器就结束了

76.改变数组长度的方法有哪些?

shift、unshift、pop、push

 

热门文章

暂无图片
编程学习 ·

MySQL 简洁速查手册

MySQL 速查手册 文章目录MySQL 速查手册0. 前言1. 开启/关闭数据库2. 数据库操作3. 数据表操作4. 字段操作5. 数据操作6. 运算符7. 高级查询(group by、having、order by、limit)8. 高级插入9. 高级删除10. 高级更新11. 联合查询12. 连接查询12.1 左外连接12.2 右外连接13. 子查…
暂无图片
编程学习 ·

XTransfer欧美本地账户可以收哪些地区的币种?

很多人注册了XTransfer账户之后,开通了XTransfer欧美本地账户。本地收款账户有两个,一个是美元的开户行是纽约的Community Federal Savings Bank(CFSB),一个是欧元的开户行是英国的 Currency Cloud。欧美本地收款账户可以用于接收欧洲、美国的本地汇款,买家通过本地清算网…
暂无图片
编程学习 ·

Centos7下redis6.0.5的详细安装步骤

Centos7下redis6.0.5的详细安装步骤: 0、官网浏览,安装wget 1、打开 https://redis.io/download,浏览最新的redis信息。 2、安装wget:执行命令:yum install wget -y 备注:-y的意思是yes 1、wget获得redis安装包 执行: wget http://download.redis.io/releases/redis-6.0…
暂无图片
编程学习 ·

大数据分析的作用有哪些

大数据分析的出现不但可以让老百姓的生活更加便捷,同时也可以提高企业的竞争力,无论是哪个行业以及具体的企业都会有与之对应的大数据分析,而今天就来说说大数据分析对于企业有哪些帮助。数据分析目的1:分类检查未知分类或暂时未知分类的数据,目的是预测数据属于哪个类别或…
暂无图片
编程学习 ·

ps处理几亿个像素点的照片时,如何保存为几十兆而又很清晰

最近几天在做年级的毕业照,照片像素大小为24400*14640,在硬盘里有1.16G。 这个时候如果用ps直接存储为png格式的话,保存的照片非常模糊,基本看不清脸。当时很苦恼,还以为几亿个像素的照片没办法既小又高清。对于这么大的照片,我百度了一下一般保存为tif格式。这是相机拍照…
暂无图片
编程学习 ·

1.古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子, * 小兔子长到第三个月后每个月又生一对兔子, * 假如兔子都不死,问每个月的兔子对数为多少? * 分析: * 月份:1 2 3

package com.ujiuye.java;/*古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,* 小兔子长到第三个月后每个月又生一对兔子,* 假如兔子都不死,问每个月的兔子对数为多少?* 分析:* 月份:1 2 3 4 5 6 7 8 9...* 对数 :1 1 2 3 5 8 13 21... */ public class Dem…
暂无图片
编程学习 ·

Java中Date类型数据格式转换

查询数据库datetime类型数据,返回的结果是Mon Jun 22 19:37:29 CST 2020 先转换成yyyy-MM-dd类型的格式。 /** * 获取现在时间 * * @return 返回短时间字符串格式yyyy-MM-dd */ public static String getStringDateShort() { Date currentTime = new Date(); SimpleDateF…
暂无图片
编程学习 ·

elementUI From表单踩坑之watch 变量监控

-当修改input框内的值(form.name)的时候,watch 监控from失败,watch中的from不相应,打印无效;<el-form ref="form" :model="form" label-width="80px"><el-form-item label="活动名称"><el-input v-model="f…
暂无图片
编程学习 ·

数据库原理及应用教程陈志泊-第三章课后习题

一、选择题1. B 2. A 3. C 4. B 5. C 6. C7. B 8. D 9. A 10. D 11. C 12. D二、填空题1. 结构化查询语言2. 数据查询、数据定义、数据操纵、数据控制3. 外模式、模式、内模式4. 数据库、事务日志5. NULL/NOT NULL 、 UNIQUE 约束、 PRIMARY KEY 约束、 FOREIGN KEY …
暂无图片
编程学习 ·

强推#vue图片预览组件—v-viewer

强推#vue图片预览组件—v-viewer 先来介绍一下背景 项目是用vue搭的,产品给的需求是:图片列表展示,要求点击图片可以放大。 原本就是写了一个弹出框,包裹相应图片就算完成了,但是!!! 作为一个善于思考的前端娃,我一定要考虑更加全面哇,因为这些图片是病人的病历拍照上…
暂无图片
编程学习 ·

ssm实现用户管理系统

ssm实现用户管理系统(2) @RequestMapping("/add.do") public String add(User user){userService.add(user);return "redirect:findAll.do"; } @RequestMapping("/toUpdate.do") public ModelAndView toUpdate(int id){User user=userService.…
暂无图片
编程学习 ·

机器学习 | 优秀Tensorflow开源项目汇总(上)

1、Open_model_zoo预先训练的深度学习模型和样本(高质量且快速)https://github.com/opencv/open_model_zoo2、Deep Learning In Productionhttps://github.com/ahkarami/Deep-Learning-in-Production3、AndroidtensorflowmachinelearningexampleAndroid TensorFlow机器学习示…
暂无图片
编程学习 ·

Java8的集合:HashSet的实现原理

HashSet 概述 HashSet 实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。 HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素…
暂无图片
编程学习 ·

最大子列和问题

实例1.1 最大子列和问题 (20分)给定K个整数组成的序列{ N​1​​, N​2​​, ..., N​K​​ },“连续子列”被定义为{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -…