JavaScript面试题 由浅到深

2,219 阅读8分钟

什么是JavaScript?

javascript是一种专门与网页交互而设计的脚本语言,由三个部分组成

  • ECMAscript,提供核心语言功能
  • 文档对象模型(DOM),提供访问和操作网页内容的方法和接口
  • 浏览器对象模型(BOM),提供与浏览器交互的方法和接口

JavaScript有什么用途

  • 嵌入动态文本于html页面
  • 对浏览器事件做出响应
  • 读写html元素
  • 在数据被提交到服务器之前验证数据
  • 检测访客的浏览器信息
  • 控制cookie,包括创建和修改等
  • 基于node.js技术进行服务器端编程

JavaScript 有哪些数据类型

  • Number 数字类型
  • String 字符出类型
  • Boolean 布尔类型
  • null 空
  • undefined 未定义
  • Object 对象 {包含 function,Array, Date}
  • symbol es6新加

JavaScript 验证数据类型

  • typeof 对与原始类型来说除了null都可以显示正确的类型,对于对象来说,除了函数都会显示object
    console.log(typeof undefined);  //undefined
    console.log(typeof 123);  //number
    console.log(typeof '123');  //string
    console.log(typeof true); //boolean
    console.log(typeof [1,2,3]);  //object 数组的数据类型在 typeof 中被解释为 object
    console.log(typeof {"id": 11}); //object
    console.log(typeof null); //object
    console.log(typeof console.log);  //function
  • instanceof可以正确的判断对象的类型,因为instanceof是通过判断对象的原型链中是不是能找到类型的prototype
    console.log(2 instanceof Number)                     // false
    console.log(true instanceof Boolean)                 // false
    console.log('str' instanceof String);                // false  
    console.log([] instanceof Array);                    // true
    console.log(function(){} instanceof Function);       // true
    console.log({} instanceof Object);                   // true    
  • instanceof 能准确的判断引用数据类型(Array,Function,Object),却不能判断基本数据类型

类型转换

  • toString() // 转换为string类型

  • Number() // 转换为number类型

  • Boolean() // 转换为boolean类型

  • 隐式转换

``` js
    var a = 123
    var b = '123'
    var c = a + b
    console.log(typeof c) // number类型转为了string类型
```

如何理解JSON

  1. JSON是JS的一个对象,也是一种数据格式,JSON中的两个api如下
    • 将JSON字符串转换成JSON对象 JSON.parse()
    • 将JSON对象转换成JSON字符串 JSON.stringify()
    JSON字符串
    var str1 ='{ "name":"JavaScript", "age": "24"}'
    
    JSON对象
    var str2 = { name: "JavaScript", age: "24"}

js数组方法

作用域和作用域链

  1. 作用域

    • 作用域是定义变量的区域,全局执行环境就是全局作用域,函数执行环境就是私有作用域,它们都是栈内存

    • 执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为

    • 全局执行环境在web浏览器中被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的,在node环境中,全局执行环境是global对象

    • 私有作用域 ---> 函数执行都会形成一个私有作用域

    • 全局作用域 ---> 页面一打开就会形成一个全局作用域

    • 私有变量 ---> 在私有作用域里面形成的变量(通过var声明)

    • 全局变量 ---> 在全局作用域形成的变量(var声明)

    • 块级作用域 --->所声明的变量在指定块的作用域外无法被访问(通过es6中的let,const来声明)

  2. 作用域链

    当代码在一个环境中执行时,会创建变量对象的一个作用域链(作用域形成的链条)
    • 作用域链的前端,始终都是当前执行的代码所在环境的变量对象

    • 作用域链中的下一个对象来自于外部环境,而在下一个变量对象则来自下一个外部环境,一直倒全局执行环境

    • 变量的查找是沿着作用域链来实现的,所以也称作作用域链为变量查找机制

    • 内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境的任何变量和函数

原型和原型链

  • 构造函数创建对象
     function Person () {
     }
     var person = new Person()
     Person.name = 'tangen'
     console.log(person.name) // tangen
  • 每一个函数都有一个prototype属性,每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
``` js
    function Person () {
        
    }
    Person.prototype.name = 'tangen'
    var person1 = new Person()
    var person2 = new person()
    console.log(person1) // tangen
    console.log(person2) // tangen

```

Person(构造函数) ->prototype->Person.protype(实例原型)

  • 每一个JavaScript对象(null除外)都有一个属性叫proto,这个属性会指向该对象的原型
  function Person() {

  }
  var person = new Person();
  console.log(person.__proto__ === Person.prototype); // true
  • 每个原型都有一个constructor属性指向关联的构造函数 实例原型指向构造函数
  function Person () {
      
  }
  console.log(Person === Person.prototype.constructor) //true

当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。

如何理解this

  • 在浏览器里,在全局范围内this 指向window对象
  • 在函数中,this永远指向最后调用他的那个对象
  • 构造函数中,this指向new出来的那个新对象
  • 通过call,apply,bind将this强绑定在指定的那个对象上,来改变this指向
  • 箭头函数中this为父作用域的this,不是调用时的this,箭头函数中this指向是静态的在声明的时候就确定下来了

什么是箭头函数

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数

    // es5
    var time = funtion () {
        return new Date()
    }
    // es6
    const time = () => new Date()
    
    // es5 
    var person = function(name){
        return name
    }
    const person = (name) => name

什么是ajax

ajax(Asynchronous JavaScript and XML(异步的 JavaScript 和 XML))

它是一种异步通信的方法,通过直接由 js 脚本向服务器发起 http 通信,然后根据服务器返回的数据,更新网页的相应部分,而不用刷新整个页面的一种方法。

  • 创建ajax步骤
    1. 创建xhr对象
        var xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');// 兼容IE6及以下版本
    
    1. 配置Ajax请求地址
      xhr.open('get','url',true)
    
    1. 发送请求
      xhr.send()
    
    1. 监听请求,接收响应
      xhr.onreadysatechange=function(){
       if(xhr.readySates==4&&xhr.status==200 || xhr.status==304 )
            console.log(xhr.responsetXML)
      }
    
  • jQuery写法
    $.ajax({
          type:'post',
          url:'',
          async:ture,//async 异步  sync  同步
          data:data,//针对post请求
          dataType:'jsonp',
          success:function (msg) {

          },
          error:function (error) {

          }
        })

  • axios(一个基于promise的http库,可以用在浏览器和node.js中)
    axios({
     method: 'post',
     url: '/user/12345',
     data: {
        firstName: 'Fred',
        lastName: 'Flintstone'
  }
});

事件冒泡和事件捕获

-事件冒泡

  1. 事件会从最内层元素开始发生,一直向上传播
  2. 当前元素 --> body --> html --> document --> window
  • 事件捕获
  1. 事件捕获:与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。
  2. window----> document----> html----> body ---->目标元素

js的深拷贝和浅拷贝

  • 浅拷贝
    • Object.assign() 方法: 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
    • 拓展运算符 ...
  • 深拷贝
    • JSON.parse(JSON.stringify(object)),缺点诸多(会忽略undefined、symbol、函数;不能解决循环引用;不能处理正则、new Date())
    • 浅拷贝+递归

单线程和异步

  • 同步会阻塞代码,但是异步不会
  • 同步
        let a = 1
        Math.floor(a)
        console.log(a)  // 1
    
  • 异步
    1. 回调
        console.log(1);
        setTimeout(function() {
              console.log(2);
            }, 0);
            console.log(3);
            setTimeout(function() {
              console.log(4);
            }, 1000);
            console.log(5);
            // 输出结果:1,3,5,2,4
    
    1. promise
            function p(time){
              return new Promise((resolve, reject) => {
                setTimeout(() => {
                  resolve(new Date());
                }, time)
              });
            }
            p(1000).then((data) => {
              console.log(1, data);
              return p(1000);
            }).then((data) => {
              console.log(2, data);
              return p(2000);
            }).then((data) => {
              console.log(3, data);
            })
    
    1. async
            function p(time) {
              return new Promise((resolve, reject) => {
                setTimeout(() => {
                   resolve(new Date());
                }, time)
              });
            }
            (async function(){
              let time1 = await p(1000);
              console.log(1, time1);
            
              let time2 = await p(1000);
              console.log(2, time2)
            
              let time3 = await p(2000);
              console.log(3, time3);
            })()
    

cookie 和localStorage以及sessionStorage

  • cookie

    • 数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递
    • cookie数据不能超过4k(主要是名字,值,过期事件,会话标识等)
    • 只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
    • 所有同源窗口共享
      // 设置cookie的名字,值,过期天数
      function setCookie(name,value,Days) {
          var exp = new Date()
          exp.setTime(exp.getTime() + Days*24*60*60*1000)
          document.cookie = name + "=" + escape(value) + ";expires=" + exp.toUTCString();
          //escape它用于转义不能用明文正确发送的任何字符
          //toUTCString() 方法可根据世界时 (UTC) 把 Date 对象转换为字符串,并返回结果。
      }
      // 获取所有cookie
      var getCookie = document.cookie
      
      // 获取指定cooKie
      function getCookie(name){
          var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
              if(arr=document.cookie.match(reg))
                  return unescape(arr[2]);
              else
                  return null;
      }
      
      // 删除cookie
      function delCookie(name) {
          var exp = new Date();
          exp.setTime(exp.getTime() - 1);
          var cval=getCookie(name);
          if(cval!=null)
          document.cookie= name + "="+cval+";expires="+exp.toGMTString();
      }
      
      // 使用示列
          setCookie("name","tangen",10);
          getCookie("name");
          delCookie("name");
    
  • localStorage和sessionStorage

    • 数据保存在浏览器端,不会自动把数据发送给服务器。
    • 大小都是5M或者更大。
    • sessionStorage:仅在当前浏览器窗口关闭之前有效,localStorage:始终有效,窗口或浏览器关闭也一直保存。
    • sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的。
      const ls = 'tangen';
      const ss = 'temporary';
      // 存
      localStorage.setItem('lsname',ls)
      sessionStorage.setItem('ssname',ss)
      // 取
      localStorage.getItem('lsname')
      sessionStorage.getItem('ssname')
      //删
      localStorage.removeItem('lsname')
      sessionStorage.removeItem('ssname')
    

http

  • http是基于tcp/ip通信来传递数据的,http是无连接的(每次连接只处理 一个请求,处理完之后就断开连接),http是无状态的(上次干过的事情这次他就不记得了)。
  • 按图讲解
  • Rquest URL: 请求的url地址
  • Request Methods: 请求的方法,主要有(post,get,put,delete,connect,options,head)
  • Status Code: 状态码(1xx,2xx,3xx,4xx,5xx);
    • 100-199:信息状态码
    • 200-299:成功状态码
    • 300-399:重定向状态码
    • 400-499:客户端错误状态码
    • 500-599: 服务端错误状态码
  • Remote Address:当前HTTP请求的远程地址,即HTTP请求的源地址
  • Referrer:链接的来源地址,Referrer Police是w3c提出的候选策略,主要用于规范Referrer
    • 九种策略(no-referrer,no-referrer-when-downgrade,origin,origin-when-cross-origin, same-origin,strict-origin, strict-origin-when-cross-origin,unsafe-url,"")
  • Content-Length:主体的长度或尺寸
  • Content-Type:主体的对象类型
  • Date: 时间日期
  • Accept:告诉服务器能够发送哪些媒体类型
  • Accept-Encoding: 告诉服务器能够发送哪些编码方式
  • Accept-Language: 告诉服务器能发送哪些语言
  • Cache-Control: 缓存控制
  • Connection: 允许客户端与服务端指定与请求/响应相连接有关的选项
  • Cookie:客户端用它向服务端发送一个令牌
  • Host:给出接收请求服务器的地址和端口号
  • Pragma:缓存控制
  • Referer:提供包含当前请求url的文档的url
  • Sec-Fetch-Dest:提取数据的方式
  • Sec-Fetch-Mode:提取元数据标头指示请求的模式
  • Sec-Fetch-Site:提取元数据标头指示请求发起方的源和资源的源之间的关系
  • User-Agent:将发送请求的应用程序名称告知服务器
  • X-Requested-With: 同步请求或异步请求

如果觉得有帮助的话 不妨给我的点个赞