js面试题

2019-12-14  本文已影响0人  Do_Du

https://www.jianshu.com/p/11bc204bb602

知识点:push返回的是数组长度

    function addToList(item, list) {
      return list.push(item)
    }
    var result = addToList('apple', ['banana'])
    console.log(result)

    // A ['apple','banana']
    // B 2
    // C true
    // D undefined
    // 正确答案:C 因为push返回的是数组长度

知识点:
|| :返回第一个布尔值为true的内容 ; 若没有true的内容最后返回最后一个内容
&& :返回第一个布尔值为false的内容 ; 若没有false的内容最后返回最后一个内容
Boolean(判断返回第一个布尔值 或者 最后一个内容 真假)

    // || 返回第一个布尔值为true的内容 ;若没有true的内容最后返回false
    // && 返回第一个布尔值为false的内容 ;若没有false的内容最后返回true
    var one = (false && {} && null)
    var two = (null && false && '')
    var three = ([] && 0 && true)
    var four = ([] && {} && true)
    console.log(one, two, three, four) // false null 0 true

    var one1 = (false || {} || null)
    var two1 = (null || false || '')
    var three1 = ([] || 0 && true)
    var four1 = (null || 0 || false)
    console.log(one1, two1, three1, four1) // {} "" [] false

    console.log('[]', Boolean([])) // true []等同于初始化一个数组 var arr = new Array()
    console.log('{}', Boolean({})) // true {}等同于初始化一个对象 var obj = new Object()
    console.log('空字符串', Boolean('')) // false
    console.log('null', Boolean(null)) // false

知识点:变量提升

console.log(a)
var a =2;

变量提升等价于

var a;
console.log(a) // 这里的a已声明未赋值,所以等于undefined
a = 2;

知识点:全局作用域
当全局变量和局部变量同名时,全局作用域变量不会作用域局部变量,并且变量会提升

var a = 1;
 function fun(){
  console.log(a) // 函数内部没有生命a变量,带有var才是声明,所以这里受外部全局变量作用,a=1
  a =2; // a变量被重新赋值
}
fun()  // 1
console.log(a) // 2
var a = 1;
 function fun(){
  console.log(a) // 函数内部有生命a变量,带有var才是声明,由于【全局作用域】,且下面a变量提升原理,这里是undefined 
  var a =2; // 函数内部变量和外部全局变量同名,全局变量不会作用于内部
}
fun()  // undefined
console.log(a) // 2

面试例子:

var a=10
function fn(){
    var b = 2*a; // 这里的aundefined,所以b=2*undefined= NaN
    var a = 20;
    var c = a + 1; // 这里的a=20
    console.log(b)
    console.log(c)
}
fn()
答案:
NaN
21

知识点:数组的元素可以进行简单的运算

    var list = [1 + 2, 1 * 2, 1 / 2]
    console.log(list) //  ['3,2,0.5']数组的元素可以进行简单的运算
   
    // A ["1+2","1*2","1/2"]
    // B ["12",2,0.5]
    // C [3,2,0.5]
    // D [1,1,1,]
    // 答案: C

知识点:window.onload: 页面html等资源文件加载完毕后才会加载的文件,当有两个onload出现的时候会执行最后一个

window.onload = function() {
  面向对象:抽象 多态 继承 封装
  对象: 成员变量 、 方法
  el: '#app',
  data: { // 成员变量 
  
  },
  methods: {
    
  }
}
var arr = [1,2,3,4]
arr.length = 1;
console.log(arr);
//答案:[1]

知识点
函数调用:a(5) 隐式等价于 window.a(5),this就指向window;即谁调用这个函数,this就指向谁
这里this指向window,var x=a(5) => 先运行右边 a(5),等价于window.x = 5,window多了个变量x=5,重新创建变量x=a(5),隐式等价于window.x = a(5) ,则x = 函数,函数返回的是this,this又指向(等于)window,所以x被重新赋值等于window,这里x和x.x都等于window,但由于随后又window.y=a(6),a(6) => window.x=6,y= window,打印y.x = 6;打印x.x = 6.6,x是number类型,故undefined

function a(xx) {this.x = xx; return this;}
var x=a(5);var y=a(6);
console.log(x.x);
console.log(y.x);
//答案:undefined 6

正常:

function a(xx) {this.x = xx; return this;}
var z=a(5);var y=a(6);
console.log(z.x);
console.log(y.x);
//答案:6 6
image.png

【js】浏览器请求一个url页面到显示完成,这个过程发生了什么?

image.png

一般会经历以下几个过程:

1、首先,在浏览器地址栏中输入url

2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。

3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。

4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。

5、握手成功后,浏览器向服务器发送http请求,请求数据包。

6、服务器处理收到的请求,将数据返回至浏览器

7、浏览器收到HTTP响应

8、读取页面内容,浏览器渲染,解析html源码

9、生成Dom树、解析css样式、js交互

10、客户端和服务器交互

11、ajax查询

其中,步骤2的具体过程是:

浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);
路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
ISP缓存:若上述均失败,继续向ISP搜索。

【js】列举3种主要数据类型,2种复合类型,2中特殊数据类型
使用typeof:判断数据类型

主要的数据类型:
字符串 - String:var str = 'abc'
数值 - Number: var num = 111
布尔 - Boolean: var bool = true

复合数据类型:
数组 - object:var arr = [1,1,1]
对象 - object:var obj = {num: 111}
方法 - function: var fun = funtion(){}

特殊数据类型:
null - object: var _null = null
undefined - undefined: var _unde = undefined

【js】数组、对象、null的typeof返回的都是object,如何object中的是数组类型呢?

法一、xxx instanceof Array:返回true即为数组
instanceof :判断一个变量(xxx)是否某个对象(Array)的实例

var arr = [1,1,1];
var brr = {num: 111};
console.log(arr instanceof Array) // true
console.log(brr instanceof Array) // false

法二、xxx.constructor == Array:返回true即为数组
constructor 属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数。

var arr = [1,1,1];
var brr = {num: 111};
console.log(arr.constructor == Array) // true
console.log(brr.constructor == Array) // false
console.log([].constructor == Array);  //true
console.log({}.constructor == Object);  //true
console.log("string".constructor == String); //true
console.log((123).constructor == Number);  //true
console.log(true.constructor == Boolean);  //true

法三、Object.prototype.toString.call(arr) === '[object Array]'

var arr = [1,1,1];
function isArray(o) {
    return Object.prototype.toString.call(o) === '[object Array]'
}
consol.log(isArray(arr)) =>返回true即为数组

**法四、Es6 Array.isArray():返回true即为数组

var arr = [1,1,1]
console.log(Array.isArray(arr)) // true

【js】说说ajax请求过程及原理

image.png
function getData(){
  var xmlhttp;
  if (window.XMLHttpRequest) { // 浏览器兼容
    xmlhttp = new XMLHttpRequest();
  }else {
    xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
  }
  xmlhttp.open('post','http://localhost:8080/api',true);
  xmlhttp.send();
  xmlhttp.onreadyStateChange = function(){
    if (xmlhttp.readyState == 4 && xmlhttp.Status == 200){
      console.log(xmlhttp.responseText)
    }
  }
}

【js】数组去重
法一、indexOf返回数组下标,返回-1即不在数组中

var arr = [1,1,1,1,2,2,3,4,4,5,6]
var arr2 = []
for(var i=0;i<arr.length;i++){
    if (arr2.indexOf(arr[i]) == -1){
        arr2.push(arr[i])
    }
}
console.log(arr2) // (6) [1, 2, 3, 4, 5, 6]

法二、includes 是否包含

var arr = [1,1,1,1,2,2,3,4,4,5,6]
var arr2 = []
for(var i=0;i<arr.length;i++){
    if (!arr2.includes(arr[i])){
        arr2.push(arr[i])
    }
}
console.log(arr2)

法三、Es6: new Set

var arr = [1,1,1,1,2,2,3,4,4,5,6]
var _arr3 = new Set(arr)
console.log(_arr3)
image.png

使用扩展运算符 返回数组

var arr = [1,1,1,1,2,2,3,4,4,5,6]
var _arr3 = new Set(arr)
var arr3 = [..._arr3]
console.log(arr3)

【js】快速删除数组中某一项

var arr= [1,2,3]
var index = arr.indexOf(1)
arr.splice(index,1)
console.log(arr) // [2,3]

简便方法:使用数组过滤方法filter
var arr= [1,2,3]
arr = arr.filter(item=>{
    return item !==1
})
console.log(arr) //  [2,3]

[js] 面试题(关于必包)
什么是必包,必包的作用

一个外部变量 + 一个函数就是必包
必包的作用把函数的变量维持在内存中
下面为必包例子

var counter = function(){
  var count = 1
  return function(){
    return count++;
  }
}
var c = counter();
console.log(c()) // 1 函数的变量维持在内存中,所以会一直递增
console.log(c()) // 2

面试题

function fun(n,obj){
    console.log(obj)
    return {
        fun: function(m){
            return fun(m,n); // 这个fun是最外层的function fun(n,obj)
        }
    }
}
var a = fun(0); a.fun(1); a.fun(2);a.fun(3) => undefined; 0;0;0;
var b = fun(0).fun(1).fun(2).fun(3) => undefined;0;1;2
var c = fun(0).fun(1); c.fun(2); c.fun(3);=> undefined;0;1;1
image.png

冒泡排序法

var arr = [0,3,5,2,1,8]
var tmp = 0;
for (var i=0;i<arr.length;i++){
    for(var j=0;j<arr.length-i;j++){
        if(arr[j]>arr[j+1]){
            tmp = arr[j+1]
            arr[j+1]= arr[j]
            arr[j] = tmp
        }
    }
}
console.log(arr) // [0, 1, 2, 3, 5, 8]

call 与apply 动态改变指针指向
call 与 apply 都是动态改变指针指向,不同的是call接收的参数是字符串,apply接收的参数是数组

var name = 'abc'
function print(){
  console.log(this.name) // 这里的this指window
}
console.log(print()) //  abc
var name = 'abc'
function print(){
  console.log(this.name) // 这里的this指window
}
var o = {name: 'bbb'}
print.call(o);  //改变指针指向o对象
print.apply(o); //改变指针指向o对象
console.log(print()) //  bbb
var name = 'abc'
function print(age, sex){
  console.log(this.name + ',' + this.age + ',' + this.sex) // 这里的this指window
}
var o = {name: 'bbb'}
print.call(o, 22,'女‘);  //改变指针指向o对象
print.apply(o, [22,'女‘]); //改变指针指向o对象
console.log(print()) 

get1_install2_app3_List4_by5_android6每个单词后面总会携带一个数字,只有偶数才删掉,写一个函数实现输出get1installapp3Listby5android

 let str = 'get1_install2_app3_List4_by5_android6';
 let newStr = [];
 str.split('_').forEach(item=>{
   let num = item.substr(item.length-1);
   if (num%2==0){
     item = item.slice(0,item.length-1);
   }
   newStr.push(item)
 })
 console.log(newStr.join(''))

不使用任何循环控制语句和迭代器的情况下实现一个0-1000的数组赋值

var arr = Array.from (new Array(1000),(v,i)=>i)

写一个函数能判断两个对象(注意特殊对象)内包含的内容是否一致

var arr = [1,1,1]
var arr2 = [1,2,1]
var arr3 = [1,1,1]
var crr = {
  a: 1,
  b:2
}
var crr2 = {
  a: 1,
  b:2
}
var crr3 = {
  a: 1,
  b:2,
  c: 3
}
var crr4 = {
  a: 11,
  b:2,
}
var drr = {
  a: 11,
  b:2,
  c: {
    aa: 1
  }
}
var drr2 = {
  a: 11,
  b:2,
  c: {
    aa: 1
  }
}
function isEqual(obj1,obj2) {
  if (!obj1 instanceof Object && !obj2 instanceof Object) {
    return obj1 == obj2
  } 
  if (Object.keys(obj1).length != Object.keys(obj2).length) {
    return false
  }
  for(var index in obj1) {
    if (obj1[index] instanceof Object && obj2[index] instanceof Object) {
      return isEqual(obj1[index],obj2[index])
    }else if (obj1[index] !== obj2[index]) {
      return false
    }
  }
  return true
}
console.log('arr2',isEqual(arr,arr2))
console.log('arr3',isEqual(arr,arr3))

console.log('crr2',isEqual(crr,crr2))
console.log('crr3',isEqual(crr,crr3))
console.log('crr4',isEqual(crr,crr4))

console.log('drr2',isEqual(drr,drr2))
上一篇下一篇

猜你喜欢

热点阅读