• 前端知识点


    1、JS基本数据类型有哪些?引用数据类型有哪些?

    在 JS 中,存在着 8 种原始值,分别是: boolean null undefined number string symbol 、Bigint(ES2020新增)
    引用数据类型:
    对象Object(包含普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数学函数-Math,函数对象-Function)

    null和undefined 有什么区别?

    (1)null是一个表示”无”的对象,转我数值是为0,undefined是一个表示”无”的原始值,转为数值时为NaN。当声明的变量还未被初始化时,能量的默认值为undefined
    (2)Null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象
    (3)Undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。
    典型用法是:
    a、变量被声明了,但没有赋值时,就等于undefined
    b、调用函数时,应该提供的参数没有提供,该参数等于undefined
    c、对象没有赋值属性,该属性的值为undefined
    d、函数没有返回值时,默认返回undefined
    (4)null表示”没有对象”,即该处不应该有值。典型用法是: a、作为函数的参数,表示该函数的参数不是对象 b、作为对象原型链的终点

    2、CSS中 link 和@import 的区别是?

    link属于HTML标签,而@import是CSS提供的;页面被加载的时link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;link方式的样式的权重 高于@import的权重.

    3、position的absolute与fixed共同点与不同点

    相同:改变行内元素的呈现方式,display被置为block;让元素脱离普通流,不占据空间;默认会覆盖到非定位元素上
    不同点:absolute的”根元素“是可以设置的,而fixed的”根元素“固定为浏览器窗口。当你滚动网页,元素与浏览器窗口之间的距离是不变的。  


    4、什么是闭包?

       我的理解是,闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

    5、谈谈你对原型链的理解

    在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象。
       当函数经过new调用时,这个函数就成为了构造函数,返回一个全新的实例对象,这个实例对象有一个__proto__属性,指向构造函数的原型对象。
       JavaScript对象通过__proto__ 指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条, 即原型链。

    实现一个instanceof

    function myInstanceof(left,right) {
        if(typeof left !== 'object' || left === null) return false
        //获取原型
        let proto = Object.getPrototypeOf(left)
        while(true){
            //如果原型为null,则已经到了原型链顶端,判断结束
            if(proto === null) return false
            //左边的原型等于右边的原型,则返回结果
            if(proto === right.prototype) return true
            //否则就继续向上获取原型
            proto = Object.getPrototypeOf(proto)
        }
    }
    

    6、关于setTimeout的一些冷知识

    • 由于消息队列的机制,不一定能按照自己设置的时间执行

    • settimeout嵌套settimeout时,系统会设置最短时间间隔为4ms

    • 未激活的页面,settimeout最小时间间隔为1000ms

    • 延时执行时间最大值为2147483647(32bit),溢出这个值会导致定时器立即执行

    7、常见兼容性问题


    浏览器默认的margin和padding不同。解决方案是加一个全局的*{margin:0;padding:0;}来统一。
    IE下,可以使用获取常规属性的方法来获取自定义属性,
       也可以使用getAttribute()获取自定义属性;
       Firefox下,只能使用getAttribute()获取自定义属性. 
       解决方法:统一通过getAttribute()获取自定义属性.
    IE下,event对象有x,y属性,但是没有pageX,pageY属性; 
      Firefox下,event对象有pageX,pageY属性,但是没有x,y属性
    解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。
    Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 
      可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决.

    超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序:
    L-V-H-A :  a:link {} a:visited {} a:hover {} a:active {}

    上下margin重合问题
    ie和ff都存在,相邻的两个div的margin-left和margin-right不会重合,但是margin-top和margin-bottom却会发生重合。
    解决方法,养成良好的代码编写习惯,同时采用margin-top或者同时采用margin-bottom。


    8、节流

    比如说事件触发可以让它在每一秒内只触发一次,可以提高性能。
    function throttle(fn, wait) {
        let prev = +new Date()
        return function() {
            let now = +new Date()
            /*当下一次事件触发的时间和初始事件触发的时间的差值大于
    			等待时间时才触发新事件 */
            if(now - prev > wait) {
                fn.apply(this, arguments)
            }
            //重置初始触发时间
            prev = +new Date()
        }
    }
    

    9、防抖

    防抖就是可以限制事件在一定时间内不能多次触发,比如说你疯狂按点击按钮,一顿操作猛如虎,不加防抖的话它也会跟着你疯起来,疯狂执行触发的方法。但是一旦加了防抖,无论你点击多少次,他都只会在你最后一次点击的时候才执行。 防抖常用于搜索框或滚动条等的监听事件处理,可以提高性能。

    function debounce(fn, wait = 50) {
        //初始化一个定时器
        let timer
        return function() {
            //如果timer存在就将其清除
            if(timer) {
                clearTimeout(timer)
            }
            //重置timer
            timer = setTimeout(() => {
                //将入参绑定给调用对象
                fn.apply(this, arguments)
            }, wait)
        }
    }
    

    深拷贝和浅拷贝

    浅拷贝: 顾名思义,所谓浅拷贝就是对对象进行浅层次的复制,只复制一层对象的属性,并不包括对象里面的引用类型数据 , 当遇到有子对象的情况时,子对象就会互相影响 ,修改拷贝出来的子对象也会影响原有的子对象

    深拷贝: 深拷贝是对对象以及对象的所有子对象进行拷贝,也就是说新拷贝对象的子对象里的属性也不会影响到原来的对象

    let obj = { a: 1, b: 2, c: { d: 3, e: 4 } }

    实现浅拷贝

    使用Object.assign()

    let obj2 = Object.assign({}, obj)
    obj2.a = 111
    obj2.c.e = 555
    console.log(obj)
    console.log(obj2)

    使用展开运算符

    let obj2 = {...obj}

    obj2.a = 111

    obj2.c.e = 555

    console.log(obj)

    console.log(obj2) 

    实现深拷贝

    最简单的深拷贝方式

    let target = JSON.parse(JSON.stringify(source))

    但是这种方法的话只支持objectarraystringnumbertruefalsenull这几种数据或者值,其他的比如函数、undefined、Date、RegExp等数据类型都不支持。对于它不支持的数据都会直接忽略该属性。

    完整版

    function deepCopy(source, cache = new Map()) {
      if (cache.has(source)) {
        //如果缓存中已经有值则直接返回,解决循环调用的问题
        return cache.get(source)
      }
      //当入参属于Object复杂数据类型就开始做子类检测-> Function Array RegExp Date 都属于Object类型
      if (source instanceof Object) {
        let target
        if (source instanceof Array) {
          //判断数组的情况
          target = []
        } else if (source instanceof Function) {
          //判断函数的情况
          target = function () {
            return source.apply(this, arguments)
          }
        } else if (source instanceof RegExp) {
          //判断正则表达式的情况
          target = source
        } else if (source instanceof Date) {
          target = new Date(source)
        } else {
          //普通对象
          target = {}
        }
        // 将属性和拷贝后的值进行缓存
        cache.set(source, target)
        //开始做遍历递归调用
        for (let key in source) {
          if (source.hasOwnProperty(key)) {
            target[key] = deepCopy(source[key], cache)
          }
        }
        return target
      } else {
        //如果不是复杂数据类型的话就直接返回
        return source
      }
    }
    
  • 相关阅读:
    GridView中实现可收缩的面板
    android之xml数据解析(Pull)
    android之xml数据解析(DOM)
    android intent 传递list或者对象
    Android之单元测试
    Directx11教程(48) depth/stencil buffer的作用
    Directx11教程(47) alpha blend(4)雾的实现
    Directx11教程41 纹理映射(11)
    Directx11教程40 纹理映射(10)
    Directx11教程(46) alpha blend(3)
  • 原文地址:https://www.cnblogs.com/zhujin/p/16130031.html
Copyright © 2020-2023  润新知