js面试题收集

链接

如何实现浏览器内多个标签页之间的通信? (阿里)

WebSocket、SharedWorker;

也可以调用localstorge、cookies等本地存储方式;

localstorge另一个浏览上下文里被添加、修改或删除时,它都会触发一个事件,

我们通过监听事件,控制它的值来进行页面信息通信;

注意quirks:Safari 在无痕模式下设置localstorge值时会抛出 QuotaExceededError 的异常

js如何判断数组是Array类型

在说明如何判断一个对象为数组类型前,我们先巩固下js的数据类型,

js一共有六大数据类型:number、string、object、Boolean、null、undefined。

var str="string";
console.log(typeof str); //string
var num=1;
console.log(typeof num); //number
var bn=false;
console.log(typeof bn); //boolean
var a;
console.log(typeof a); //undfined
var obj = null;
console.log(typeof obj); //object
var doc = document;
console.log(typeof doc);//object
var arr = [];
console.log(arr); //object
var fn = function(){};
console.log(typeof fn); //function

除了前四个类型外,null、对象、数组返回的都是object类型;

对于函数类型返回的则是function,再比如typeof(Date),typeof(eval)等。接下来进入正题,
js判断数组类型的方法。

  • 方法一: 使用instanceof方法

    instanceof 用于判断一个变量是否某个对象的实例,左边操作数是一个对象,右边操作数是一个函数对象或者函数构造器。

    原理是通过判断左操作数的对象的原型链上是否具有右操作数的构造函数的prototype属性。

    a instanceof b?alert("true"):alert("false")
//注意b值是你想要判断的那种数据类型,不是一个字符串,比如Array。

举一个例子:
    var arr=[];
    console.log(arr instanceof Array) //返回true
  • 方法二: 使用constructor方法

    在W3C定义中的定义:constructor

    属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数。

    从定义上来说跟instanceof不太一致,但效果都是一样的。

    那么判断各种类型的方法:

    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
注意:

使用instaceof和construcor,被判断的array必须是在当前页面声明的!

比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),
在子页面中声明了一个array,并将其赋值给父页面的一个变量,
这时判断该变量,Array ==object.constructor;会返回false;

原因:

1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。

2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,
是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array。
  • 方法三: 使用Object.prototype.toString.call(arr) === '[object Array]'方法
function isArray(o) {
      return Object.prototype.toString.call(o);
    }
    var arr=[2,5,6,8];
    var obj={name:'zhangsan',age:25};
    var fn = function () {}
    console.log(isArray(arr)); //[object Array]
    console.log(isArray(obj)); //[object Object]
    console.log(isArray(fn));  //[object function]
  • 方法四:ES5定义了Array.isArray:

    Array.isArray([]) //true

js扩展运算符(spread)是三个点(…)

// ES6 的写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

合并两个数组并去重(ES5和ES6两种方式实现)

https://blog.csdn.net/qingmengwuhen1/article/details/79876813

  • ES6实现方式

let arr1 = [1, 1, 2, 3, 6, 9, 5, 5, 4]
let arr2 = [1, 2, 5, 4, 9, 7, 7, 8, 8]
function uniqueArr(arr1,arr2) {
    //合并两个数组
    arr1.push(...arr2)
    //或者arr1 = [...arr1,...arr2]
    //去重
    let arr3 = Array.from(new Set(arr1))
    //let arr3 = [...new Set(arr1)]
    console.log(arr3) 
}

uniqueArr(arr1,arr2)

注:new Set()接收一个数组,并且数组中的元素是唯一的。Array.from()能把伪数组转化为真正的数组。

  • ES5实现方式1
var arr1 = [1, 1, 2, 3, 6, 9, 5, 5, 4]
var arr2 = [1, 2, 5, 4, 9, 7, 7, 8, 8]
function uniqueArr(arr1, arr2){
    var arr3 = arr1.concat(arr2)
    var arr4 = []
    for(var i=0,len=arr3.length; i<len; i++) {
        if(arr4.indexOf(arr3[i]) === -1) {
            arr4.push(arr3[i])
        }
    }
    console.log(arr4)
} 
uniqueArr(arr1, arr2)
    

合并多个对象并且去重的2种写法(es6)

let objOne = {a:1};
let objTwo = {b:2};
let objThree = {b:4,c:5};
let obj = Object.assign(objOne,objTwo,objThree);
console.log(obj)    // {a:1,b:4,c:5}
let obj1={...objOne,...objTwo,...objThree};
console.log(obj1)   // {a:1,b:4,c:5}

什么是事件循环(Event Loop)

执行栈与事件队列

堆(heap)和栈(stack)中来加以区分。其中,堆里存放着一些对象。而栈中则存放着一些基础类型变量以及对象的指针。

js引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将这个事件挂起,继续执行栈中的其他任务。当一个异步事件返回结果后,js会将这个事件加入与当前执行栈不同的另一个队列,我们称之为事件队列。被放入事件队列不会立刻执行其回调,而是等待当前执行栈中的所有任务都执行完毕, 主线程处于闲置状态时,主线程会去查找事件队列是否有任务。如果有,那么主线程会从中取出排在第一位的事件,并把这个事件对应的回调放入执行栈中,然后执行其中的同步代码…,如此反复,这样就形成了一个无限的循环。这就是这个过程被称为“事件循环(Event Loop)”的原因

this指向

  • ① this指向的,永远只可能是对象!

  • ② this指向谁,永远不取决于this写在哪!而是取决于函数在哪调用。

  • ③ this指向的对象,我们称之为函数的上下文context,也叫函数的调用者。

  • 通过函数名()直接调用:this指向window

 
function func(){
    console.log(this);
}
        
//① 通过函数名()直接调用:this指向window
func(); // this--->window

  • ② 通过对象.函数名()调用的:this指向这个对象
function func(){
    console.log(this);
}

//② 通过对象.函数名()调用的:this指向这个对象
// 狭义对象
var obj = {
name:"obj",
func1 :func
};
obj.func1(); // this--->obj

// 广义对象
document.getElementById("div").onclick = function(){
this.style.backgroundColor = "red";
}; // this--->div
  • ③ 函数作为数组的一个元素,通过数组下标调用的:this指向这个数组
function func(){
    console.log(this);
}

//③ 函数作为数组的一个元素,
通过数组下标调用的:
this指向这个数组
var arr = [func,1,2,3];
arr[0]();  // this--->arr
  • ④ 函数作为window内置函数的回调函数调用:this指向window( setInterval setTimeout 等)

function func(){
    console.log(this);
}

//④ 函数作为window内置函数的回调函数调用:
this指向window
setTimeout(func,1000);// this--->window
//setInterval(func,1000);
  • ⑤ 函数作为构造函数,用new关键字调用时:this指向新new出的对象

function func(){
    console.log(this);
}

//⑤ 函数作为构造函数,
用new关键字调用时:
this指向新new出的对象
var obj = new func(); //this--->new出的新obj

几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构?

基本数据类型:Undefined、Null、Boolean、Number、String

值类型:数值、布尔值、null、undefined。

引用类型:对象、数组、函数。

堆栈数据结构:是一种支持后进先出(LIFO)的集合,即后被插入的数据,先被取出!

js数组中提供了以下几个方法可以让我们很方便实现堆栈:

shift:从数组中把第一个元素删除,并返回这个元素的值。

unshift: 在数组的开头添加一个或更多元素,并返回新的长度

push:在数组的中末尾添加元素,并返回新的长度

pop:从数组中把最后一个元素删除,并返回这个元素的值。

const let var

与之相比var let const三种,前者因为var的变量会提升到window,但是let个const不会,let ,const会生成块作用域,同一作用域下let和const不能声明同名变量,而var可以

GET和POST的区别,何时使用POST?

  • GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符
  • POST:一般用于修改服务器上的资源,对所发送的信息没有限制。

GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,

也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。

然而,在以下情况中,请使用 POST 请求:

  • 无法使用缓存文件(更新服务器上的文件或数据库
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值