js面试题

87 阅读10分钟

1、js是什么? js是一种运行在浏览器中的解释性语言,脚本语言,js是单线程的

2、数据类型有哪些?怎么判断? 基本数据类型: 数字类型:number 布尔类型:boolean 字符串类型:string

引用数据类型:
    数组:Array
    对象:object
    函数:function

特殊数据类型:
    null
    undefined
    NaN

检测数据类型的方法:
    typeof:检测基本数据类型,不能检测nullobject、array
    Array.isArray():检测数组类型
    isNaN:检测不是一个数字
    ===:可检测所有类型

3、js中=、==、===区别? =:赋值 ==:等于 --- 只比较大小,不会比较数据类型 ===:全等于 --- 大小、数据类型都比较

4、i++与++i的区别? i++:先赋值后运算 ++i:先运算后赋值

5、while 和 dowhile 区别: while必须是条件成立才能执行循环体 do while就算条件不成立也能执行一次循环

6、break 和 continue 区别: break: 终止循环,看到break后面代码就不执行了 continue: 跳出当前循环,开始执行下一次循环

7、小九九默写 var num = 1; for (let i = 1; i <= 9; i++) { for (let j = 1; j <= i; j++) { num = i * j document.write(i + 'x' + j + '=' + num); } document.write('
') }

8、递归函数?会经常用吗?缺点是什么? 递归函数:函数中自己调用自己的函数 公司中一般禁止使用递归函数 因为递归函数必须等待最后结果的出现,才能完成逻辑执行,违背了垃圾回收机制,所以不能使用

9、forEach和for区别: forEach不能使用break、没有返回值 ,其return返回的是undefined

10、全局变量 和 局部变量 全局变量;在函数体外部声明的变量 ,其中省略var的变量称为全局变量(省略var的全局变量禁止使用) 特点:函数体内部和外部都可以使用

局部变量:在函数体内部声明的变量
    特点:只能在函数体内部使用

11、什么是预解析?---- 即作变量的提升和函数的提升 在预解析中,变量(函数)的提升只作用在当前的作用域中,并且会提升到当前作用域最上方

12、数组常用方法有哪些?(11个) push(): 将元素添加到数组的结尾,添加多个用逗号隔开 pop(): 删除数组的最后一项

    splice(): 删除指定元素,并在删除位置添加元素 --- 3个参数:起始索引  删除数目  新增内容

    String()、toString(): 将数组转成字符串
    join(): 把数组转换成字符串,然后给他规定一个连接字符,默认是逗号
    split(): 把字符串转换成数组,字符串以什么符号连接,就以什么符号分割

    unshift(): 将元素添加到数组的开头,添加多个用逗号隔开
    shift(): 删除数组的第一项

    -----------------------------------------

    sort(): 对数组排序,正序
    reverse(): 对数组进行颠倒
    concat(): 合并数组,返回一个新数组

13、什么是命名函数、匿名函数、递归函数、回调函数、函数表达式? 命名函数:有名字的函数 匿名函数:没有名字的函数 函数表达式;用变量调用的函数

    递归函数:函数中自己调用自己的函数
    回调函数:以函数为参数的函数
        应用场景:一个函数访问另一个函数内部的变量
 
    构造函数:
    闭包函数:

14、数组的遍历 循环获取数组中的每一项

遍历方法:
    forfor infor of、 forEach

for in循环:获取的是下标
for of循环:获取的是内容

for of属性:
    values(): 获取的是内容(默认值) 
    keys(): 获取的是下标
    entries():获取的是下标和内容

forEach和for区别:
        forEach不能使用break、没有返回值 ,其return返回的是undefined

15、冒泡排序 前后两个数进行比较,如果符合条件,就交换两个数的位置 每一轮,都会找到一个比较大的数,放在数组最后

外循环 --- 循环次数
内循环 --- 比较次数,比较相邻两个数的大小,如果前一个数比后一个数大,就交换两者位置

代码:
    var arr = [9,8,17,6,5,4]

    // 控制循环次数   
    for (let i = 0; i < arr.length-1; i++) {
        // 控制比较次数
        for (let j = 0; j < arr.length-1-i; j++) {
            if (arr[j] > arr[j+1]) {//比较
                
                // 交换
                var temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp
            }
            
        }
    }
    console.log(arr);

16、获取dom的方法? document.getElementById() document.getElementsByTagName() document.getElementsByName() document.getElementsByClassName()

document.querySelector('选择器') --- 获取单个节点
document.querySelectorAll('选择器') --- 获取多个节点,伪数组

document.parentNode 获取父节点
document.children: 获取子节点 不会获取换行 --- 伪数组
document.nextElementSibling:获取下一个兄弟
document.previousElementSibling:获取上一个兄弟

事件委托 --- event

17、操作dom的方法? appendChild:添加节点到最后 insertBefore:在某个元素前面插入 removeChild:删除子节点 remove:删除子节点 replaceChild:修改子节点 cloneNode:克隆子节点

18、innerHTML和innerText的区别 相同点;都可以获取或设置内容 innerHTML:以代码形式设置/获取内容 innerText:以文本形式设置/获取内容

19、js获取或设置属性的方法 通过dom进行获取或设置内置属性 --- dom.属性 通过getAttribute获取自定义属性 通过setAttribute设置自定义属性

20、怎样提升浏览器的加载速度 ****** 文件的外部引入(外部引入) 减少冗余代码,将代码进行封装(代码封装) 使用事件委托代替dom获取,减少dom操作(事件委托) 图片的懒加载 --- 懒加载:按需加载(懒加载) 压缩文件(文件压缩)

21、什么是事件冒泡?怎么阻止事件冒泡? 定义:两个div两两嵌套,都添加点击事件,点击里面的div,会触发外面div的点击事件 解决:event.stopPropagation()

22、事件绑定 作用:给同一个元素添加多个相同的事件(设置不同的处理函数) 语法: 绑定 --- dom.addEventListener('事件名称',函数名/函数) 解绑 --- dom.removeEventListener('事件名称',函数名/函数)

原因:相同事件会被替换掉,只执行最后一个

23、设置类名的方法 className:追加类名 --- 设置类名时,要把之前的类名也加上 classList.add() --- 直接追加类名 setAttribute() --- 设置任何属性 classList.remove() --- 删除类名

24、什么是window对象,什么是document对象? window对象就是BOM也是浏览器,封装了窗口标题、工具栏、地址栏、状态栏等成员对象 document对象就是DOM也是网页,代表html整个文档,可以用来访问网页中所有元素 DOM属于BOM

25、for in 和 for of 区别: for in 可以直接遍历对象,得到属性 遍历数组,得到下标 for of 不可以直接遍历对象,因为没有引入iterable,必须加上 Object.key(对象) 才能使用 遍历数组,得到内容

26、this理解: 普通函数中,如果没有调用者,this属于window,如果有调用者,this属于调用者 在对象中,如果是普通函数,this属于这个对象

27、深拷贝和浅拷贝的区别 浅拷贝: b复制了a,当修改a时,b中的子元素不会随着a变化而变化,但是b中子对象中的元素会随着a变化而变化 即:原数据变化时,复制的数据的第一层不会改变,第n层(n>=2)会发生改变

    实现方法:
        slice()、concat()、es6剩余运算符 (...arr 展开)

深拷贝:
    b复制了a,当修改a时,b中的元素都不会随着变化,拥有独立内存
    即:原数据变化时,复制的数据不会发生改变

    实现方法:
        JSON.parse(JSON.stringify())、jquery的extend方法(已淘汰)、递归拷贝

28、什么是面向对象? 定义:不管对象内部原理,只是使用它对外的功能

组成:属性和方法

特点;抽象、封装、继承、多态
    抽象:抽指把核心的东西抽出来
    多态:不同对象作用在同一操作时,产生不同的效果

29、什么是构造函数? 用new关键字来调用的函数

构造函数自动做了什么?
    自动创建了一个空白对象
    自动将结果返回

30、继承模式 方法1:call()或apply()

方法2:原型链
    每一个构造函数中都会有一个原型,查找属性时先去对象中找,
    对象中找不到,再去他的原型中找,如果原型里没有,就去原型里的原型中找,以此类推,形成原型链

方法3: 利用空对象作为中介

31、异步和同步的区别: 异步:(打电话)执行完一个方法后,必须等待数据的返回,只有在收到消息后,才能执行其他命令 同步:(收发短信)执行完一个方法后,不必等待数据的返回,可以直接执行其他命令

32、http定义?http的三次握手? http是一种网络传输协议,浏览器作为http客户端通过url向http服务器发起请求,服务器接收请求后,向客户端发送响应信息

三次握手:
    1、客户端向服务端发送请求
    2、服务端接收到请求需要进行核对,发送的请求服务器能不能收到,如果收到,就向客户端返回接收到的请求信息
    3、客户端拿着服务器返回成功接收到的这个信息,再去向服务器发送请求,两者才能建立联系

33、请求的方式有哪些?post和get的区别? delete put post get等

post和get的区别:
    1、安全性问题
        get请求参数会被拼接到地址栏上,信息会暴露
        post请求参数不可见

    2、数据传输量
        get有长度限制
        post不会

    3、缓存问题
        get数据会被缓存
        post不会

    4、后端的习惯
        数据的增删改查
        查询:get,因为要分页,有长度限制
        增删改:post
    

34、常见状态码: *200 请求成功 301 资源被永久转移到其他url *400 客户端请求语法错误 401 发送请求需要被认证 *403 请求的资源被服务器拒绝 *404 服务器无法找到指定的资源 *500 服务器在执行请求是发生了错误 *502 服务器网关发生了错误 503 服务器停机维护,无法处理请求

35、创建ajax步骤: *1、创建XMLHttpRequest对象,即创建一个异步调用对象 *2、创建一个http请求,并指定请求方法,建立连接 *3、发送http请求 *4、获取返回的数据

100、类型转换方法 转数字: Number() 转数字 --- 整数或小数 parseInt() 转整数 --- 直接截取小数 parseFloat() 转小数

转字符串:
    toString()、String()

转布尔:
    Boolean() --- 有具体的值就会转成true,空字符串、null、0、NaN、undefined 都会转成false

四舍五入:
    round()

保留小数后几位:
    toFixed()

向上、向下取整:
    ceil()、floor()

数组转字符串:
    String()、toString()、join()

字符串转数组:
    split()

字符截取:
    substring()
    substr()

字符串修改:
    replace()

json字符串 ------> json对象 的方法:
    1、JSON.parse
    2eval() --- 可以转成对象,但不会检验json格式

json对象 ------> json字符串 的方法:
    JSON.stringify()