zoukankan      html  css  js  c++  java
  • 2js考点和面试题

     

    做题的本质:
    拿到面试题,第一反应考点(知识点)是什么,而不是题目本身.所以先到知识点再到题目

    考点1:js基本数据类型

    typeof

     可以识别所有的基本数据类型

    可以识别函数类型。

    不可识别具体的引用类型

    总结:除了Functon外的构造函数的new 出来的实例类型都是'object'。面试时候出了typeof function基本就是function

     typeof null==='object'// JavaScript 诞生以来便如此 null是空指针对象

    console.log(typeof 1); //'number'
    console.log(typeof 'a'); //'string'
    console.log(typeof true); //'boolean'
    console.log(typeof undefined); //'undefined'
    console.log(typeof {
      a: 12
    }); //'object'
    console.log(typeof null); //'object'
    
    
     console.log(typeof [1, 2]); //'object' 
    console.log(typeof new Date()); //'object'

    console.log(typeof function () {}); //'function'
    console.log(
    typeof Math.max); //'function' //除Function外所有构造函数的类型都是'object'

    console.log(typeof new String('abc'));
    console.log(
    typeof new Number(123));
    console.log(
    typeof new Function()); //‘function’

     null undefined

    null表示没有对象,即表示该处不应该有值

    用于对象原型链的终点

    undefined 表示该处缺少一个值,只不过尚未定义

    变量初始化但未赋值,默认值是undefined;函数参数默认undefined;函数默认返回时是undefined;对象不存在的属性,该属性值是undefined

    ==&=== 

     ==默认有数据类型隐式转换 ===严格等于(类型相等,数值相等)实际开发中建议多使用=== 
     

    深拷贝

    function deepClone(obj) {
      // 如果不是引用类型(默认就是一些基本数据类型和函数类型和undefined)直接返回
      if (typeof obj !== 'object' || obj === null) {
        return obj;
      }
      let result
      if (obj instanceof Array) {
        result = []
      } else {
        result = {}
      }
      // for-in循环 array 和object都可以使用 便利key
      for (let key in obj) {
        if (!obj.hasOwnProperty(key)) continue
        // 递归拷贝
        result[key] = deepClone(obj[key]);
      }
      return result
    }
    View Code

    考点2:原型和原型链

     每个实例对象默认都有__proto__隐式属性,每个类默认自带prototype显示属性。实例.__proto__===类.prototype。上图中Student.prototype本身也是一个对象

    当前实例首先查找自身属性,
     
    如果找不到自动通过__proto__查找原型对象上的属性(原型对象里面基本存实例方法)
     

     手写instanceof

    object instanceof constructor

    instanceof 运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。

     console.log(s instanceof Student);//true

    console.log(s instanceof Person);//true
    console.log(s instanceof Object);//true
    实例对象s。 s.__proto__=Student.prototype
    s.__proto__.__proto__=Perosn.prototype
    s.__proto__.proto__.__proto__=Object.prototype
    function instance_of(leftObject, rightConstructor) {
      let rightProto = rightConstructor.prototype
      let leftValue = leftObject.__proto__
      while (true) {
        if (leftValue === null) return false
        if (leftValue === rightProto) return true
    
        leftValue = leftValue.__proto__
      }
    
    }
    View Code

    手写 call apply bind

    将函数设为对象属性值,执行对象的函数方法,删除该对象的函数属性和属性值(函数)

    // call bind apply 作用手动指定函数中的上下文this fn.call(context) 此时 fn函数中的this===context
    const obj = {
      name: 'zs',
      age: 12,
      gender: 'male',
    }
    
    function fn(a, b) {
      console.log(this);
      console.log(a, b);
    }
    
    Function.prototype.call1 = function (context, ...rest) {
      // call函数中的this是fn
      context = Object(context) || window
      context.fn = this
      context.fn(...rest) //这句话是本质
      delete context.fn
    
    }
    fn.call1(obj, 1, 2)
    
    
    Function.prototype.bind1 = function (context, ...rest) {
      context = Object(context) || window
      context.fn = this
      return () => {
        context.fn(...rest)
      }
    }
    const fn2 = fn.bind1(obj, 1, 2)
    fn2()
    
    function fn1(arr) {
      console.log(arr);
    }
    Function.prototype.apply1 = function (context, arr) {
      context = Object(context) || window
      context.fn = this
      context.fn(arr)
    
    }
    View Code

     手写 new

    创建一个空对象,这个空对象的__proto__指向构造函数的prototype 这样保证构造出来实例对象可以访问构造函数原型上实例方法 Object.create

     执行构造函数,给空对象赋属性值 call|apply,这个时候空对象里面就有属性和属性值。

    返回这个空对象。

    // Object.create(obj)方法创建一个新空对象{},使用现有的对象obj来提供新创建的对象的__proto__。
    // 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
    // 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
    // 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
    function _new(Constructor, ...args) {
      const obj = Object.create(Constructor.prototype)
      const res = Constructor.call(obj, ...args) //给空对象赋属性值
      return res instanceof Object ? res : obj
    }
    const p = _new(Person, 'zs', 10)
    View Code

     手写Object.create

    function create(obj) {
        function Fn() {}
        Fn.prototype = obj
        return new Fn()
    
      }
    View Code

    考点3:js作用域和闭包

    es6转es5

    https://www.jianshu.com/p/8a8f7b0f887a

     闭包的形式

    手写防抖和节流

    函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

    函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

    区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。
     // 防抖函数
        function debounce(fn, delay) {
          let timer = null //闭包
          return function () {
            timer && clearTimeout(timer)
            timer = setTimeout(() => {
              fn.apply(this, arguments) //频繁操作之后最后一次执行代码 注意:箭头函数里面没有this arguments参数。
              timer = null
            }, delay)
          }
        }


    //防抖2 作用一样 写法不一样而已
    function debounce1(fn, delay) {
      let timer = null
      return (...args) => {
        timer && clearTimeout(timer)
        timer = setTimeout(() => {
          fn(...args)
        }, delay)

      }
    }
     

    例子

    输入框防抖

        const input = document.querySelector('input');
    
        function fn(e) {
          const value = e.target.value
          console.log(value);
        }
        // 防抖函数
        function debounce(fn, delay) {
          let timer = null //闭包
          return function () {
            timer && clearTimeout(timer)
            timer = setTimeout(() => {
              fn.apply(this, arguments) //频繁操作之后最后一次执行代码
              timer = null
            }, delay)
          }
        }
        fn = debounce(fn, 500)
        input.addEventListener('input', fn, false);
    View Code
  • 相关阅读:
    线程池
    多线程随笔
    注解随笔
    反射机制
    iO流
    FastDFS+docker建立分布式文件系统
    Java之Exception
    Java之String
    手写SpringMvc
    spring中一些常用注解的含义
  • 原文地址:https://www.cnblogs.com/xiaoliziaaa/p/13790489.html
Copyright © 2011-2022 走看看