js基础面试准备内容

js基础知识

题目

  1. JS中使用typeof能得到的哪些类型?(考点:变量类型)
    object,string,number,boolean,function,undefined

  2. 何时使用"===",何时使用"==",为什么要使用"==="?(考点:强制类型转换)

    (1) Object.is的用法跟"==="的用法一样

    if (obj.a == null) { // 判断对象属性a是否存在
      // 这里相当于 obj.a === null || obj.a === undefined,简写形式
      // 这是jquery源码中推荐的写法。
    }
    // 所以,除了这个之外,其他的全部都用===
    

    (2)

    • 一致性:使用"=="对一致性没有任何好处,那么为什么不避免使用呢。
    • 简单和性能:一般来说,"==="是最简单的操作符,因为它不用进行类型转换。javaScript引擎的性能参差不齐,但是在大部分浏览器中"==="比"=="速度更快。
    • 即使会自动转换,但并不总是按你需要的方式转换。比如7+“3”;//"73"
  3. JS中有哪些内置函数?(考点:数据封装类对象)
    Object,Array,Boolean,Number,String,Function,Date,RegExp,Error

  4. JS变量按照存储方式区分为哪些类型,并描述其特点
    (1)值类型(或基本类型),特点:内存存储
    (2)引用类型,特点:指针

  5. 如何理解JSON
    JSON 是一个 JS 对象,同时也是一种数据格式。

      JSON.stringify({ a: 10, b: 20 })
      JSON.parse('{"a":10,"b":20}')
    

知识点

1.变量类型

  • 值类型vs引用类型

    {
      // 值类型
      let a = 100
      let b = a
      a = 200
      console.log(b) // 100
    }
    
    {
      // 引用类型,b指针指向a,包含对象、数组、函数
      // 为什么出现引用类型?节省内存空间
      let a = { age: 20 }
      let b = a
      a.age = 21
      console.log(b) // 21
    }
    
  • typeof运算符详解

    {
      // typeof只能区分值类型的详细类型,不能区分引用类型(引用类型里面只能区分函数)
      // 值类型
      console.log(typeof undefined) // undefined
      console.log(typeof 'abc') // string
      console.log(typeof 123) // number
      console.log(typeof true) // boolean
      // 引用类型
      console.log(typeof {}) // object
      console.log(typeof null) // object
      console.log(typeof console.log) // function 
    }
    

2. 变量计算

  • 强制类型转换

    {
      // 字符串拼接 
      let a =  100 +  100 // 200
      let b = 100 + '100' // 100100
    }
    
    {
      // == 运算符,会进行强制类型转换
      100 == '100' // true, 100转化为‘100’
      0 == '' // true, 0和‘’都会转化为false
      null == undefined // true, null和undefined都会转化为false
    }
    // 因此,== 运算符要慎用,只要把 == 运算符改成 === 运算符上诉问题不会出现 
    
    {
     // if 语句,出现 false 的几种情况
     if (false) {}
     if ('') {} // false
     if (0) {} // false
     if (NaN) {} // false
     if (null) {} // false
    }
    
    {
     // 逻辑运算,判断一个变量会被当做true还是false
     let a = 100
     console.log(!!a)
    }
    

原型和原型链

题目

  1. 如何准确判断一个变量是数组类型 

    var arr = []
    arr instanceof Array // true
    typeof arr // object typeof 是无法判断是否是数组的
    
  2. 写一个原型链继承的例子

    面试时不要这么写(´;ω;`)
    // 动物
    function Animal() {
      this.eat = function () {
        console.log('animal eat')
      }
    }
    // 狗
    function Dog () {
      this.bark = function() {
        console.log('dog bark')
      }
    }
    Dog.prototype = new Animal()
    //哈士奇
    var hashiqi = new Dog()
    
        function Elem (id) {
          this.elem = document.getElementById(id)
        }
        Elem.prototype.html = function(val) {
          var elem = this.elem
          if(val) {
            elem.innerHTML = val
            return this // 链式操作
          } else {
            return elem.innerHTML
          }
        }
        Elem.prototype.on = function(type, fn) {
          var elem = this.elem
          elem.addEventListener(type, fn)
          return this
        }
        var div1= new Elem('div1')
        console.log(div1.html())
        div1.html('

    hello imooc

    ') div1.on('click', function(){ alert('clicked') })

  3. 描述 new 一个对象的过程
    创建一个新对象,this指向这个新对象,执行代码,即对this赋值,返回this

知识点

1.构造函数

function Foo(name, age) {
  this.name = name
  this.age = age
  this.class = 'calss-1
  // return this //默认有这一行
}
var f = new Foo('zhangsan', 20)
var f1 = new Foo('lidi', 22)

2.构造函数 - 扩展

  • var a = {} 其实是 var a = new Object() 的语法糖
  • var a = [] ... var a = new Array() ...
  • function Foo(){...} 其实是 var Foo = new Function(...)
  • 使用 instanceof 判断一个函数是否是一个变量的构造函数

3.原型规则和原型链的构成

5条原型规则如下:

  • 所有的引用类型(数组,对象,函数),都具有对象特性,即可自由扩展属性(除了 “null” 意外)
  • 所有的引用类型(数组,对象,函数),都有一个__proto__属性(隐式原型),属性值是一个普通的对象
  • 所有的函数,都有一个prototype属性(显示原型),属性值是一个普通的对象
  • 所有的引用类型(数组,对象,函数),__proto__属性值指向它的构造函数的“prototype”属性值
  • 当试图得到一个对象的属性时,如果这个对象本身没有这个属性,那么会去它的
    __proto__(即它的构造函数的prototype)中寻找

      var obj = {} obj.a = 100
      var arr = [] arr.a = 100
      function fn() {} fn.a = 100
      console.log(obj.__proto__) // 对象
      console.log(fn.prototype) //对象
      console.log(obj.__proto__ === Object.prototype) // true
    
      function  Foo(name, age) {
        this.name = name
        // this.age = age
      }
      Foo.prototype.alertName = function () {
        alert(this.name)
      }
      var f = new Foo('zhangsan')
      f.printName = function () {
        console.log(this.name)
      }
      f.printName()
      f.alertName()
      f.toString() // 要去f.__proto__.__proto__中查找
    

    如下图所示:
    f.__proto__ 指向Foo,f.__proto__.__proto__指向Object
    Object的__proto__指向null是一个特例,是为了不造成死循环

4.instanceof

定义:用于判断引用类型属于哪个构造函数的方法
用法:

// 判断f的__proto__是否是Foo
f instanceof Foo // true
f instanceof Object // true

作用域和闭包

题目

  1. 说一下对变量提升的理解
    变量定义(执行上下文的概念)
    函数声明(注意和函数表达式的区别)

  2. 说明this几种不同的使用场景
    this要在执行时才能确认值,定义时无法确认。执行的场景如下:

    • 作为构造函数执行
    • 作为对象属性执行
    • 作为普通函数执行
    • call apply bind
    var a = {
      name:'a',
      fn: function(){
        console.log(this.name)
     }
    }
    a.fn() // this === a
    a.fn.call({name: 'B'}) // this === {name: 'B'}
    var fn1 = a.fn
    fn1()  // this === window
    
  3. 创建10个标签,点击的时候弹出来对应的序号(考点:变量提升)

    var i
    for (i = 0; i < 10; i++) {
    (function (i) { // 避免变量提升的问题
      var a = document.createElement('a')
      a.innerHTML = i + '
    ' a.addEventListener('click', function (e) { e.preventDefault() alert(i) }) document.body.appendChild(a) })(i) }
  4. 如何理解作用域
    自由变量
    作用域链,即自由变量的查找
    闭包的两个场景

  5. 实际开发中闭包的应用

    // 闭包实际应用中主要用于封装变量,收敛权限
    function isFirstLoad() {
      var _list = []
      return function (id) {
        if(_list.indexOf(id) >= 0) {
          return false
        } else {
          _list.push(id)
          return true
        }
      }
    }
    var firstLoad = isFirstLoad()
    fistLoad(10) // true
    fistLoad(10) // false
    fistLoad(20) // true
    // 你在 isFirstLoad 函数外面,根本不可能修改 _list 的值
    

知识点

1. 执行上下文

范围:一段\ // 返回callback
```

服务端设置 http header

response.setHeader()

存储

题目

  1. 请描述一下cookie,sessionStorage和localStorage的区别?
    • 容量
    • 是否会携带到ajax中
    • API易用性

知识

1. cookie

定义:本身用于客户端和服务端通信,但是它有本地存储的功能
缺点:

  • 存储量太小,只有4kB
  • 所有http请求都带着,会影响获取资源的效率
  • API简单,需要封装才能用 document.cookie = ...

2. sessionStorage 和 localStorage

定义:html5 专门为储存设计,最大容量 5M
优点:

  • api简单易用

sessionStorage 和 localStorage 的区别:标签页关闭和浏览器关闭的区别
注意:ios safari隐藏模式下,localStorage.getItem 会报错,建议统一使用 try-catch 封装

关于开发环境

知识点

1. git 代码版本管理,多人协作开发

网络git服务器如coding.net(国内) github.com
常用命令:详情查看git操作笔记

2. JS 模块化

  • 不使用模块化:
    基础utils -> 业务autils -> 应用
    问题:(1)全局变量污染,(2)顺序不能乱,依赖关系不清楚

  • 使用模块化:
    export的utils -> export的autils -> 应用require

  • AMD:
    需要异步加载JS,使用AMD

  • CommonJS:
    使用npm之后建议使用CommonJS
    不会异步加载JS

3. 打包工具 编译、压缩

  • npm init
  • npm i webpack --save-dev // 开发环境
  • npm i jquery -- save // 上线环境
  • npm i moment --save
  • npm uninstall moment --save // 卸载

4. 上线回滚的流程

  • 代码合并到 master
  • 将当前服务器的代码全部打包并记录版本号,备份
  • 将 master 分支的代码提交覆盖到线上服务器,生成新版本号 
  • 将当前服务器的代码打包并记录版本号,备份
  • 将备份的上一个版本号解压,覆盖线上的服务器,并生成新版本号 

运行环境

题目

  1. 从输入url到得到html的详细过程
    详情查看下面知识点 -> 页面加载过程

  2. window.onload 和 DOMcontentLoaded 的区别
    (1)window.onload:页面的全部资源加载完才会执行,包括图片、视频等
    (2)DOMcontentLoaded:DOM渲染完即可执行,此时图片、视频可能没有加载完

  3. 为什么要把css放在head中?
    如果不放在head中,浏览器会先渲染默认的值,再根据得到的css重新渲染,引发多次渲染。

知识点

1. 页面加载过程

  1. 加载资源的形式: 

    • 输入url,跳转页面
    • 加载html中的静态资源:css,img,js,等
  2. 加载一个资源的过程

    • 浏览器根据DNS服务器得到域名的IP地址,比如baidu.com域名->ip地址
    • 向这个IP的机器发送http请求
    • 服务器收到、处理并返回http请求
    • 浏览器得到返回内容
  3. 浏览器渲染页面的过程

    • 根据 HTML 结构生成 DOM Tree
    • 根据 css 生成 CSSOM
    • 将DOM 和 CSSOM 整合成 RenderTree
    • 根据 RenderTree 开始渲染和展示
    • 遇到

你可能感兴趣的:(前端)