这是前端最基础的问题,也是在面试中难倒无数同学的经典问题

01. Javascript 数据类型

  Javascript 数据类型 = 基本类型 + 引用类型

  ES6 之前 5 + 1 = 6 种

  ES6 之后 6 + 1 = 7 种

  注:基本类型共6种:Number 数值型, String 字符型, Boolean 布尔型, Null 空, Undefind 未定义, Symbol 符号型, 其中Symbol是ES6新增的。

    引用类型只有1种:Object 对象,注意:Function 和 Array 都继承于Object。

02. Javascript 类型判断

  Javascript 类型判断主要有三种方法

  ①  typeof

    最大的问题是判断数组和null等数据类型时,无法获得预期的结果。

  ②  instanceof

    用于判断引用类型的继承关系,如:判断Function是否继承于object

    最大的问题是不支持基本类型判断

  ③  Object.prototype.toString.call()

    类型判断的最佳实践,使用Object原型上的toString方法,这种方法可以精确的判断各种数据类型。

03.  Javascript 函数调用

  ①  直接调用

    function test(msg) {

     console.log(msg)

    }

    test ('Hello word !')

    这种方法最为常用,使用括号即可调用函数。

  ②  方法调用

    const f = {

       a: 1,

     b(){ console.log(this.a) }   

    }

    f.b()  // 1

    当函数被保存为对象的一个属性时,称为方法。当它被调用时this将绑定到该对象。

  ③  构造函数调用

    function test() {

        this.a = 1    

    }

    const o = new test()

    console.log(o.a)  // 1

    当使用new来调用函数时,会创建一个新对象,函数内部的this会绑定到新对象。

  ④  call 和 apply 调用

    Object.prototype.toString.call({})   // [object Object]

    Object.prototype.toString.apply([])  // [object Array]

    函数也是一个对象,可以拥有方法,call 和 apply 就是函数的方法,任何函数都包含call 和 apply这两个方法,调用它们可以执行函数并改变this的指向。

04.  Javascript 函数调用 bind call 和 apply 的区别

    ①  bind

      function test() {

         // this默认指向window

         console.log(this.a)

      }

      test.bind({a: 1})  // 返回一个新函数

      bind 的作用是改变函数的 this 指向,通过 bind 将 this 绑定到新对象,并返回一个新的函数。

    ②  call

      function test(b,c) {

       console.log(this.a, b, c)

      }

      test.call({a: 1}, 2, 3)   // 1 2 3

      call 的作用是执行函数并改变this指向,既然是执行函数,所以需要传入执行参数,call传参的方式是依次传入,用逗号分隔。

    ③  apply    

      function test(b,c) {

       console.log(this.a, b, c)

      }

      test.apply({a: 1}, [2, 3])   // 1 2 3

      apply 的作用和 call 类似,只是 传参方式不同, apply 将参数全部放置到一个数组当中。

05.  Javascript 变量提升

    ①  基本概念:变量可以后定义先使用。

      a = 2

      console.log(a)  // 2

      var a = 1

      console.log(a)  // 1

      如 后定义了变量 a,但可以在之前使用,是因为变量 a 的定义过程被提前了。

    

    ②  函数同样支持变量提升,可以使用后定义的提升

      test()   // 123

      function test() {

       console.log('123)

      }

    注意:字面量定义的函数不支持变量提升

      test()   // error:test is not a function

      var test = function() {

       console.log('123)

      }

      因为 test 变量会进行提升,并且默认值为 undefined。只有执行到赋值语句时,test 才会 变成一个函数。

06.  Javascript 作用域

    主要分三种,常用的是全局作用域和函数作用域

    ①  全局作用域

      var a = 123

      function test() {

       console.log(a)

      }

      test()   // 123

      全局作用域的变量,在函数中是可以被访问的,是因为作用域链在起作用,函数内部查找作用域没有找到变量 a 后,会到它的父级作用域,即全局作用域去查找。

    ②  函数作用域

      function test() {

       var a = 123

      }

      console.log(a)   // undefined

      函数作用域的变量,在全局作用域中是无法被访问的,要解决这个问题要通过闭包。

      解决方法:

      function test() {

       var a = 123

       return function() {

        return {

         a

        }

       }

      }

      console.log(test()().a)  // 123

      在函数中返回一个函数会形成一个闭包,通过闭包我们可以访问到函数作用域下的变量。

07.  Javascript 异常处理

    分为被动触发和主动抛出

    ①   // Uncaught ReferenceError: a is not defined

      console.log(a)

       上面的代码由于没有定义变量 a , 所以会触发未定义错误,属于被动触发。

    

    ②   // Uncaught Error: crash

      throw new Error('crash')

      主动抛出需要使用 throw 关键字,后面需要实例化一个 Error 对象。

    ③  如果希望主动捕获异常,可以通过 try  catch ,

      try {

       console.log(a)

      } catch(err) {

       console.error(err)

      }

      通过 try 捕获异常,catch 处理异常。

08.  Javascript 原型

    术语:1. 实例(对象):通过构造函数创建出来的对象叫做实例(对象)    注:实例对象可以有多个

       2. 实例化:构造函数创建出来的对象过程

       3. 成员:对象的属性和方法的一个统称

  一.  prototype

    ①  任何一个函数都有 prototype 属性

      function Person() {}   //  构造函数

      console.dir(Person)   // ƒ Person()  >  prototype: {constructor: ƒ}

    ②  函数的 prototype 属性值是一个对象,这个对象叫做原型 (或叫做原型对象)

      function Person() {}   // Person 是函数也是一个对象

      console.log(Person.prototype)    // {constructor: ƒ}   // 这个就是原形对象

    

    ③  作用:通过构造函数创建的实例对象 可以直接访问这个构造函数的 prototype 属性 上的任意成员。 

                   p                                                    原型

      function Person() {}

      console.log(Person.prototype)   // 原型对象

      var p = new Person()     // 这就是通过构造函数创建的实例对象

      //  现在给原型对象添加 .color 属性 值为 lime

      Person.prototype.color = "lime"
      Person.prototype.legs = 2
      console.log(Person.prototype)    //  {color: "lime", constructor: ƒ}
      console.log(p.color)    //  lime     
      console.log(p.legs)   //  2   发现 p对象可以访问到 color 属性,有值的,这个 color 的值就来源于原型。
 
  二.  __proto__ (注意:是双下滑线)
      ①  任何一个对象都有 __proto__ 属性
         对象的 __proto__ 属性值指向了当前构造函数的 prototype 属性值。
        function Person() {}
        var p = new Person()
        console.log(p.prototype)
        console.log(p.__proto__)
        console.log(Person.prototype === p.__proto__)     // true
      
      ②  要想访问到原型对象,有两种途径:
        1. 通过构造函数的 prototype 属性
        2. 通过实例对象的 __proto__ 属性
         注意:__proto__ 是个私有的属性,该属性不是标准属性,存在兼容性问题(IE不兼容),所以不要在项目中使用 __proto__ 属性(本地用用即可)
 
   三. constructor  
      ①  constructor 是原型对象中自带的属性
        function Person() {}
        var p = new Person()
          console.log(p.constructor  ===  Person)     // true
        console.log(p.constructor  ===  Person.prototype. constructor )     // true
 
   四.  原型三角函数 关系拟人化
      ①  构造函数 和 原型对象 之间的关系 : 配偶关系
         妈妈    爸爸
        1. 妈妈 通过 prototype 访问 爸爸
        2. 爸爸 通过 constructot 访问 妈妈
 
      ② 构造函数 和 实例对象 之间的关系 :母子关系
        妈妈    孩子
        1. 妈妈 通过 new 创建 孩子
        2. 孩子 不可以 直接访问到 妈妈 (关系不是很融洽)
 
      ③ 原型对象 和 实例对象 之间的关系 :父子关系
        爸爸    孩子
        1. 孩子 通过 __proto__ 属性 访问 爸爸
        2. 孩子 通过 爸爸 的 constructot 属性访问到 妈妈
        
 
09.  Javascript  词法作用域
    概念:是指 函数会根据它的创建位置 决定其 this 指向。
 
    ① 案例:
      var a = 1 
      function test() {
       console.log(this.a)  // 1
      }
      函数 test 创建于全局,所以他的 this 指向 window , this.a 获取到的是 window.a ,等于 1
 
    ②  案例(非常容易混淆)
      var a = 1 
      function test() {
       console.log(this.a) 
      }
 
      var o = {
       a: 2,
       fn() {
        var a = 3
        test()
       }
      }

      o.fn()   // 1

      该案例中共定义了 3 个 a ,从直觉上来说 o.fn 函数执行后,应该获取 o.a ,即打印 2 ,但实际结果打印了 1 ,是因为 test 创建于全局,所以它的 this 仍然指向 window ,这与它的调用环境无关。

前端必会的Javascript经典面试题的更多相关文章

  1. JavaScript经典面试题(二)

    前言: 近年来T行业就业者越来越多,有关于编程行业的高薪工作也变得越来越难找,竞争力越来越大,想要在众多的应聘者当中脱颖而出,面试题和笔试题一定要多加研究和琢磨,以下记录的是自己的面试过程之中遇到的一 ...

  2. 20道JavaScript经典面试题

    该篇文章整理了一些前端经典面试题,附带详解,涉及到JavaScript多方面知识点,满满都是干货-建议收藏阅读 前言 如果这篇文章有帮助到你,️关注+点赞️鼓励一下作者,文章公众号首发,关注 前端南玖 ...

  3. 前端javaScript经典面试题

    1.alert(1&&2),alert(1||0) alert(1&&2)的结果是2 只要“&&”前面是false,无论“&&”后面是t ...

  4. javascript经典面试题之for循环click

    经典重现 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf- ...

  5. JavaScript经典面试题系列

    1.javascript的typeof返回哪些数据类型 Object number function boolean underfind 2.例举3种强制类型转换和2种隐式类型转换? 强制(parse ...

  6. JavaScript经典作用域问题(转载)

    题目 var a = 10; function test(){ a = 100; console.log(a); console.log(this.a); var a; console.log(a); ...

  7. 15分钟带你了解前端工程师必知的javascript设计模式(附详细思维导图和源码)

    15分钟带你了解前端工程师必知的javascript设计模式(附详细思维导图和源码) 前言 设计模式是一个程序员进阶高级的必备技巧,也是评判一个工程师工作经验和能力的试金石.设计模式是程序员多年工作经 ...

  8. web前端经典面试题大全及答案

    阅读目录 JavaScript部分 JQurey部分 HTML/CSS部分 正则表达式 开发及性能优化部分 本篇收录了一些面试中经常会遇到的经典面试题以及自己面试过程中遇到的一些问题,并且都给出了我在 ...

  9. 2018 BAT最新《前端必考面试题》

    2018 BAT最新<前端必考面试题> 1.Doctype作用? 严格模式与混杂模式如何区分?它们有何意义? (1). 声明位于文档中的最前面,处于 标签之前.告知浏览器的解析器,用什么文 ...

随机推荐

  1. assign()与create()的区别

    Q:assign()与create()的区别? A:let obj = Object.assign(targetObj, -sourceObj) 作用:将一个或多个源对象自身的可枚举属性与目标对象的属 ...

  2. 移动端touch事件——单指拖拽

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  3. VPS系统后台性能优化实战

    作者: 刘用, 现任新东方APP团队高级软件工程师 2019年开始,新东方APP团队启动了长达半年以上的稳定性建设工作,为什么稳定性如此重要?因为随着每年30%以上的高速增长,现有的后端服务完全扛不住 ...

  4. php ltrim() rtrim() trim()删除字符空格

    php$str=" 去除前后空格 ";echo "方括号中为原始字符串:[".$str."]";echo "原始字符串长度:&qu ...

  5. SpringMVC笔记(2)

    一.SpringMVC的数据响应 1.1 数据响应方式 1.1.1 页面跳转 直接返回字符串 将返回的字符串与内部资源视图解析器的前后缀拼接 进行访问(默认为转发) 通过ModelAndView对象返 ...

  6. Linux系统的日志管理、时间同步、延迟命令at

    方便查看和管理 /var/log/messages ?系统服务及日志,包括服务的信息,报错等等 /var/log/secure ? ? ? ? 系统认证信息日志 /var/log/maillog ? ...

  7. 01_Keil与Proteus联合仿真的注意事项

    01. 关于keil5和Proteus8的联合仿真的操作步骤,这里就不细说,给个链接,步骤差不多是最齐全的 CSDN博客链接:https://blog.csdn.net/wzk456/article/ ...

  8. Linux档案权限篇之一

    一.查看档案的属性 "ls" 第一列为档案的权限: d:代表是目录 -:代表是文件 l:代表是连接文件(相当于windows里面的快捷方式) b:代表块设备(如硬盘) c:代表字符 ...

  9. JS006. 详解自执行函数原理与数据类型的快速转换 (声明语句、表达式、运算符剖析)

    今天的主角: Operator Description 一元正值符 " + "(MDN) 一元运算符, 如果操作数在之前不是number,试图将其转换为number. 圆括号运算符 ...

  10. 珠峰2016,第9期 vue.js 笔记部份

    在珠峰参加培训好年了,笔记原是记在本子上,现在也经不需要看了,搬家不想带上书和本了,所以把笔记整理下,存在博客中,也顺便复习一下 安装vue.js 因为方便打包和环境依赖,所以建意npm  init  ...