谈谈我在面试中遇到的javascript中常见的几个问题

一、js的数据类型有哪些

1、基本类型:

Boolean(布尔类型),String(字符串类型),Number(数字类型),Null,Undefined,Bigint还有一个es6新增的Symbol。

2、引用类型:

Object(对象),Function(函数),Array(数组)

二、js的内存存储的方式

1、栈内存:引擎执行代码时工作的内存空间,除了引擎,也用来保存基本类型数据和引用数据类型的地址

2、堆内存:用来保存一组无序且唯一的引用类型值。可以使用栈中的键名来获取


基本数据类型放在栈内存里面;

引用数据类型有一个占位在栈内存里,真实的数据在堆内存中,并且占位有一个指针指向对应的内存空间。这就是为什么const可以对原引用数据类型进行修改,而不能重新赋值一个新对象的原因。一是因为指针未发生改变,二是因为指针指向新的内存地址会报错。

如果,我们使用const声明的是一个对象的话是可以修改值的,因为这个常量不能修改指的是指向的地址不能修改,我只是修改里面的内容,堆空间地址是不变的,所以是可以修改的。

三、js中如何判断是不是一个数组

1. 通过 instanceof 判断

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在原型链中的任何位置,返回一个布尔值

let a=[ ];
a instanceof Array   //true


let b={ }
b instanceof Array  //false

2. 通过 constructor 判断

实例的构造函数属性 constructor 指向构造函数,那么我们通过 constructor 属性也可以判断是否为一个数组。

let a =[1,2,3,4]
a.constructor === Array    //true

3. 通过 Array.isArray() 判断

Array.isArray()  用于确定传递的值是否是一个数组,返回一个布尔值。

let a =[1,2,3]
Array.isArray(a)  //true

4. 通过 Object.prototype.toString.call() 判断

Object.prototype.toString.call() 可以获取到对象的不同类型 

let a=[1,2,3]

Object.prototype.toString.call(a)=== '[object Array]' //true 

它不仅仅可以检测是否是数组,还可以检测是否是一个函数或者数字等等

let a=function (){}

Object.prototype.toString.call(a)=== '[object Function]' //true 

let b=3

Object.prototype.toString.call(b)=== '[object Number]' //true 

四、let、const、var的区别

1. var声明的变量会挂载在window上,而let和const声明的变量不会

var a=1;

console.log(window.a)  // 1

let b=1;
console.log(window.b)  //undefined


const c=1;
console.log(window.c)  //undefined

2. var声明变量存在变量提升,let和const不存在变量提升 

console.log(a);  //undefined
var a = 1;

let b = 1;
console.log(b);  //1

console.log(b2)  //报错
let b2 = 1;

console.log(c);  //报错
const c = 1;

3. let 和 const 声明形成块级作用域

if () {
	var a = 10;
	let b = 10;
}
function fn() {
   return {
	  a: 100,
   };
}
fn();
console.log(a);  //100
console.log(b);  //报错:b is not defined

4. 同一作用域下 let 和 const 不能声明同名变量,而var可以

const a = 1;
const a = 4;   //报错:标识符'a'已经声明

var b=1;
var b=2;        //不会报错

let c=1;
let c=2;       //报错:标识符'c'已经声明

5. const 声明时的事项

  1. 一旦声明必须赋值.
  2. 声明后不能在修改.
  3. 如果声明的是引用类型数据,可以修改.

五、 JS常见的设计模式有那些

单例模式,工厂模式,适配模式,观察者模式等

单例模式:就是保证一个类里面只有一个实例,实现的方法一般是先判断实例存在与否。如果存在就直接返回,不存在就创建了在返回。单例作为一个命名空间的提供者,从全局命名空间提供一个唯一访问点来访问该对象

观察者模式:观察者模式的工作就是在解耦。让耦合的双方都依赖于抽象,不是依赖于具体。从而使一方的变化不会影响到另外一方.

六、es6新增语法

let/const 箭头函数 模板字符串 解构赋值 等

let/const

Const声明一个常量

let声明一个变量不会变量提升

箭头函数

箭头函数没有this 他的this指向上一层

模板字符串

let a=18
console.log(`李磊${a}岁了`)//李磊18岁了

解构赋值

数组解构,函数参数解构 对象解构

七、阻止事件冒泡的方式

冒泡事件:比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡

阻止冒泡事件有三种方法:

1.event.stopPropagation()方法

$('.btn').click(function (even) {
		even.stopPropagation();
		alert('按钮被点击了');
	})

 这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开。
例如:

<a href="https://www.csdn.net/" class="box">
	<button class="btn">按钮</button>
</a>

2.event.preventDefault()方法 

$('.btn').click(function (even) {
		even.preventDefault();
		alert('按钮被点击了');
})

这是阻止默认事件的方法,调用此方法是,连接不会被打开,但是会发生冒泡,冒泡会传递到上一层的父元素; 

3.return false ;

$('.btn').click(function (even) {
		alert('按钮被点击了');
		return false;
})

 这个方法比较暴力,他会同事阻止事件冒泡也会阻止默认事件;写上此代码,连接不会被打开,事件也不会传递到上一层的父元素;可以理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault()

八、==和===的区别

==是比较值相等即可

console.log(1=='1') //true

===不仅比较值是否相等还要比较数据类型是否相同

console.log(1==='1') //false
console.log(1===1)//true

九、 判断JS的数据类型

1. typeof

typeof主要用来判断基本数据类型 他返回的数据类型是字符串 (注意:typeof来判断null和引用数据类型 返回的结果都是 ‘object’

typeof 1          //number
typeof 'a'        //string
typeof true       //boolean
typeof undefined  //undefined  
typeof null       //object
typeof {}         //object 
typeof [1,2,3]    //object

function Fn(){}
typeof new Fn()    //object

typeof new Array() //object

2.instanceof

instanceof 后面一定要是对象类型,并且大小写不能错 (专门判断引用数据类型

console.log(a instanceof Array)   //true
console.log(b instanceof Date) 
console.log(c instanceof function)    //true
console.log(d instanceof function)     //false

十、 js常见的创建方式

//1.实例化创建  new
var obj=new Obj();
obj.name="磊磊"
obj.age=18
obj.say=function(){
   console.log(this.name)
}

//2.直接创建
let obj1={
name:"磊磊",
age:18
}

//3.自定义构造函数创建对象
 let OBJ=new obj2("磊磊",18)
    function obj2(name,age){
        this.name=name;
        this.age=age;
        console.log(this.name);
   }   

十一、 map和forEach的区别

1.map()会分配内存空间储存新的数组并且返回 foreach()不会返回新的数据

2.foreach()允许callback改变原数组的内容。map()返回新的数组。

3.map多用于复杂的逻辑运算中 在react中循环多数用map

十二、 数组去重的方法

1.双重for循环去重

//数组去重
   function disTinct(arr) {
       var ans = []
       for (var i = arr.length - 1; i >= 0; i--) {
           var nb = 0 //没重复为0.有重复不为0
           for (var j = i - 1; j >= 0; j--) {
               if (arr[i] == arr[j]) {
                   nb = 1
                   break
               }
           }
           if (nb == 0) {
               ans.unshift(arr[i])
           }
       }
       return ans
   }

2. indexof去重

//数组去重(indexOf)
function unique(arr) {
    var res = []
    for (var i = 0; i < arr.length; i++) {
        if (res.indexOf(arr[i]) == -1) {
            res.push(arr[i])
        }
    }
    return res
}

3. sort排序后循环数组去重 

function unique(arr){
  var arr2 = arr.sort();
  for(var i=1;i<arr2.length;){
    if(arr2[i] === arr2[i-1]){
      arr2.splice(i,1);       
    }else{
           i++;
        }
  }
  return arr2;
}

十三、 number和parseint的区别 

parseInt() 函数:

parseInt()函数用于解析字符串并将其转换为指定基数的整数。它需要两个参数,要解析的字符串和要使用的基数。基数是一个介于2和36之间的整数,表示数字的基数。

如果parseInt()在解析过程中遇到不符合指定基数的字符,它将忽略该字符和所有后续字符。然后它将解析到该点的值作为一个整数返回。在这种情况下,允许使用前导或尾随的空格。

如果parseInt()函数得到参数如果以数字开头,就会返回开头的合法数字部分;如果以非数字开头,则它将返回NaN。此NaN值不是任何基数的有效数字,不能用于任何数学计算。

语法:

parseInt(string, radix)

Number()函数:

Number()函数用于创建基本类型Number对象。它接受一个参数,即数字的值。此值可以使用字符串传递,Number函数将尝试将其表示为数字。如果参数无法转换为数字,则返回NaN值。此NaN值不是有效数字,不能用于任何数字计算。

语法:

Number(valueString)

parseInt()和Number()之间的区别

1、当转换的内容包含非数字的时候,Number() 会返回NaN(Not a Number);parseInt() 要看情况,如果以数字开头,就会返回开头的合法数字部分,如果以非数字开头,则返回NaN。

2、parseInt()仅返回整数值的区别,而Number()返回包括浮点的所有数字。

十四、 Eventloop机制

这个是js的一个底层运行的原理 因为js的单线程的。但是一些耗时的任务会影响到我们的执行效率。这样我们使用异步的时候 会单独开辟出来一个异步线程。将这些耗时的放在异步线程中。等主线程里面执行完毕之后,再从异步队列中取出一个到主线程中执行。执行完之后在在异步线程中取出第二个。这个过程就是eventloop循环机制

十五、防抖和节流

防抖是指我们在连续对一个事件进行操作的时候,这个事件只会按照固定每n秒执行一次的时间执行

(就是为了防止用户连续点击多长清除相同的数据 造成浏览器和服务器频繁的接收带来的压力)

节流大多用于搜索框等地方 是指我们在连续操作一个事件的时候,这个事件不会执行,只有等我们操作完成之和等n秒后自己执行

(也是减少浏览器和服务器的压力)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值