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

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. opencv入门系列教学(二)图像入门:读取、展示并保存视频

    一.从相机读取视频 通常情况下,我们必须用摄像机捕捉实时画面.让我们从摄像头捕捉一段视频(我使用的是我笔记本电脑内置的网络摄像头) ,将其转换成灰度视频并显示出来.        要捕获视频,我们需要 ...

  2. mysql各个版本驱动jar包下载 mysql/mysql-connector-java/5.1.22

    想下个jar csdn上全是要积分下载,这里记录下 下载地址,免得到时又要找 http://central.maven.org/maven2/mysql/mysql-connector-java/

  3. MySQL双主+Keepalived高可用

    原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 基础环境 二 实际部署 2.1 安装MySQL 2.2 初始化MySQL 2. ...

  4. Spring源码浅析之bean实例的创建过程(二)

    在上一篇内容中,介绍了doGetBean方法的源码内容,知道了bean在创建的过程中,有三个范围,单例.多例.Scope,里面都使用到了createBean.下面本篇文章的主要内容,就是围绕creat ...

  5. docker开启remote-api 2375端口后,Failed to start Docker Application Container Engine,重启docker失败的问题解决

    1.  按照网上的教程修改了 /usr/lib/systemd/system/docerk.service配置后,重启失败.修改/etc/docker/daemon.json 增加hosts后重启也是 ...

  6. java 多线程Thread和Runnable的区别

    如果一个类继承Thread,则不适合资源共享.但是如果实现了Runable接口的话,则很容易的实现资源共享 实现Runnable接口比继承Thread类所具有的优势:1. 适合多个相同的程序代码的线程 ...

  7. 使用shell脚本实现everthing的功能

    我们知道,在 Windows 下,有一款非常实用的神器,叫作 Everything ,它可以在极短的时间里,搜索出来你所想要的文件/目录,如下图示: Linux 下也有一些类似于 everything ...

  8. Windows phone 8 触发器使用小结

    引用空间: xmlns:ec="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expres ...

  9. 谈谈如何进阶Java高级工程师

    从入门到瓶颈(++文末附学习脑图++) 首先,先自我介绍一下,楼主94年的,四川人,普通大专毕业. 第一阶段 实习阶段 2015年,实习阶段去浙江温州(没错,就是皮革厂的那个地方)找了份软件实施的工作 ...

  10. 机器学习——EM算法

    1 数学基础 在实际中,最小化的函数有几个极值,所以最优化算法得出的极值不确实是否为全局的极值,对于一些特殊的函数,凸函数与凹函数,任何局部极值也是全局极致,因此如果目标函数是凸的或凹的,那么优化算法 ...