test

防抖:屡次触发事宜后,事宜处置惩罚函数只实行一次,并且是在触发操纵结束时实行。

    function debounce(fn) {
      // 4、竖立一个标记用来寄存定时器的返回值
      let timeout = null;
      return function() {除
        clearTimeout(timeout);
        var args = arguments;
        timeout = setTimeout(() => {
          fn.apply(this, args);
        }, 1000);
      };
    }
    sayDebounce(){
     console.log("防抖胜利!");
    }
    btn.addEventListener("click", debounce(sayDebounce));

撙节: 触发函数事宜后,短时刻距离内没法一连挪用,只需上一次函数实行后,过了划定的时刻距离,才举行下一次的函数挪用

    var throttle = function(func, delay) {
        var prev = Date.now();
        return function() {
            var context = this;
            var args = arguments;
            var now = Date.now();
            if (now - prev >= delay) {
                func.apply(context, args);
                prev = Date.now();
            }
        }
    }
    function handle() {
        console.log(Math.random());
    }
    window.addEventListener('scroll', throttle(handle, 1000));
    // 处置惩罚函数
    function handle() {
        console.log(Math.random()); 
    }
    // 转动事宜
    window.addEventListener('scroll', debounce(handle, 1000));

js 完成once 要领

function runOnce(fn, context) { //掌握让函数只触发一次
  return function () {
    try {
      fn.apply(context || this, arguments);
    }
    catch (e) {
      console.error(e);//平常能够解释掉这行
    }
    finally {
      fn = null;
    }
  }
}
var obj = {name: "狗子", age: 24};
var canOnlyFireOnce = runOnce(function () {
  console.log("你好" + this.name);
}, obj);
canOnlyFireOnce(); //你好天际孤雁
canOnlyFireOnce(); // nothing

完成bind 或许 call

Function.prototype.bind= function(obj){
    var _self = this, args = arguments;
    return function() {
        _self.apply(obj, Array.prototype.slice.call(args, 1));
    }
}
Function.protype.call = function(context){
    context = context || window
    context.fn = this;
    const args = [...arguments].slice(1);
    const result = context.fn(...args);
    delete context.fn
    return result;
}

reduce完成map

    const reduceMap = (fn, thisArg /*真想去掉thisArg这个参数*/ ) => {
        return (list) => {
            // 不怎么情愿写下面这两个推断前提
            if (typeof fn !== 'function') {
                throw new TypeError(fn + 'is not a function')  
            }
            if (!Array.isArray(list)) {
                throw new TypeError('list must be a Array')
            }
            if (list.length === 0) return []
            return list.reduce((acc, value, index) => {
                return acc.concat([ fn.call(thisArg, value, index, list) ])
            }, [])
        }
    }
    // 来运用下怎样🧐
    reduceMap(x => x + 1)([ 1, 2, 3 ]) // [ 2, 3, 4 ]
    
    const mapAry1 = reduceMap(function(item) {
        console.log(this)
        return item + 1
    }, { msg: 'mapping' })([ 1, 2, 3 ]) 

完成一个函数delay(alert,3,4000)(“hello”),每距离4秒打印一次“hello”,打印三次。

  function delay(fn,nums,times){
    return async function(content){
      for(var i = 0; i<nums; i ++){
        await new Promise(resolve =>{
          setTimeout(()=>{
            fn.call(this, content);
            resolve(true);
          }, times)
        })
      }
    }
  }
  delay(console.log, 3, 4000)('hello');

setTimeout 完成 setInterval

function setInterval(func, t){
    var inter = function(){
        setTimeout(inter,t);
        try{
            func.call(null);
        }
        catch(e){
            throw e.toString();
        }
    }
    setTimeout(inter,t);
};

JS完成找出字符串中涌现最多的字符和次数

      function getMost(str){
        var obj = {};
        for(var i =0; i< str.length; i ++){
          var char =  str.charAt(i);
          if(obj[char]){
            obj[char] ++;
          }else {
            obj[char] = 1; 
          }
        }
        var max = 0;
        var maxChar = null;
        for(var p in obj) {
          if (max <obj[p]){
            max = obj[p];
            maxChar = p;
          }
        }
        return `涌现最多的字符:${maxChar},共涌现${max}`
      }

手写一个双向绑定,input输入的值相应在p标签上

<body>
    <div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
</div>
</body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
</script>

长度为N的数组,两数相加为sum

function findGroup(arr,n,sum){
    if (sum == 0 && n == 0) {
        return true;
    } else if (n <= 0) {
        return false;
    }
    if (n > 0) {
        for (var i = 0; i < arr.length; i++) {
            var temp = arr.slice(i+1,arr.length);
            return findGroup(temp,n-1,sum-arr[i]) || findGroup(temp,n,sum);
        }
    }
}
function getNum(arr, sum) {
    if (!Array.isArray(arr)) return null;
    arr.sort();
    for (var i = 0; i < arr.length - 1; i++) {
        if (arr[i] > sum) continue;
        var restNum = sum - arr[i];
        // 斟酌下为何要 > i
        if (arr.indexOf(restNum) > i) return [arr[i], restNum];
    }

    return null;
}

伪数组转换为数组的要领

   Array.from(arr);
   Array.protype.slice(arr, 0);

rem规划道理

(function(){
    var html = document.querySelector('html');
    changeRem();
    window.addEventListener('resize', changeRem);
    function changeRem() {
        var width = html.getBoundingClientRect().width;
        html.style.fontSize = width / 10 + 'px';
    }
})()

new的道理是什么?经由历程new的体式格局竖立对象和经由历程字面量竖立有什么区分?

1.竖立一个新对象。
2.这个新对象会被实行[[原型]]衔接。
3.将组织函数的作用域赋值给新对象,即this指向这个新对象.
4.假如函数没有返回其他对象,那末new表达式中的函数挪用会自动返回这个新对象

ts和js的区分,为何要挑选运用ts?

JavaScript 是轻量级的解释性脚本语言,可嵌入到 HTML 页面中,在阅读器端实行。而TypeScript 是JavaScript 的超集,即包括JavaScript 的一切元素,能运转JavaScript 的代码,并扩大了JavaScript 的语法。比拟于JavaScript ,它还增添了静态范例、类、模块、接口和范例注解方面的功用,更易于大项目标开辟。
1.便于开辟人员做解释。
2.能协助开辟人员检测出毛病并修正。
3.TypeScript东西使重构更变的轻易、快速。
4.TypeScript 引入了 JavaScript 中没有的“类”观点。
5.TypeScript 中引入了模块的观点,能够把声明、数据、函数和类封装在模块中。
6.范例平安功用能在编码时期检测毛病,这为开辟人员竖立了一个更高效的编码和调试历程。

HTTP1.0、HTTP1.1、HTTP2.0的关联和区分(重点)

HTTP1.0:

无状况、无衔接

HTTP1.1:

耐久衔接
要求管道化
增添缓存处置惩罚(新的字段如cache-control)
增添Host字段、支撑断点传输等(把文件分红几部份)

HTTP2.0:

二进制分帧
多路复用(或衔接同享)
头部紧缩
服务器推送

对象的深拷贝与浅拷贝(重点)

浅拷贝:仅仅复制对象的援用,而不是对象本身;
Object.assign()
深拷贝:把复制的对象所援用的悉数对象都复制一遍。
JSON.parse(JSON.stringify(initalObj)

完成多个标签页之间通讯的几种要领

websocket
localstorage: onstorage事宜。

vue-router 道理

1. hash: 运用 URL hash 值来作路由。默许形式。
    window.addEventListener('hashchange', matchAndUpdate)
2. history: 依靠 HTML5 History API 和服务器设置。检察 HTML5 History 形式。
    pushState replaceState window.onpopstate
3. abstract形式
    abstract形式是运用一个不依靠于阅读器的阅读汗青假造治理后端。依据平台差别能够看出,在 Weex 环境中只支撑运用 abstract 形式。 不过,vue-router 本身会对环境做校验,假如发明没有阅读器的 API,vue-router 会自动强迫进入 abstract 形式

vue-router 钩子

全局导航钩子
    router.beforeEach(to, from, next),
    router.beforeResolve(to, from, next),
    router.afterEach(to, from ,next)
组件内钩子
    beforeRouteEnter: 在衬着该组件的对应路由被 confirm 前挪用
    beforeRouteUpdate: 在当前路由转变,然则该组件被复用时挪用
    beforeRouteLeave:  导航脱离该组件的对应路由时挪用
零丁路由独享组件
    beforeEnter

Object.defineProperty瑕玷

一: Object.defineProperty没法监听数组的变化,所以vue在监听数组的变化时偶然不能做到双向绑定。

    // 遍历对象,对其属性值举行挟制
    Object.keys(data).forEach(function(key) {
      Object.defineProperty(data, key, {
        enumerable: true,//可罗列
        configurable: true,//可转变
        get: function() {
          console.log('get');
        },
        set: function(newVal) {
          // 当属性值发生变化时我们能够举行分外操纵
          console.log(`大家好,我是${newVal}`);
          say(newVal);
        },
      });
    });
    data.name = '蔡康永'; //真正的贵族

二: Object.defineProperty监听的是对象的属性,当监听的对象有许多层级组成,则须要递归对象直至基础范例,才举行监听,比较贫苦。比拟Proxy监听全部对象的体式格局,就轻易许多。

CSRF

跨站要求捏造,击者盗用了你的身份,以你的名义发送歹意要求。
防备CSRF进击
只管运用POST,限定GET

  1. 只管运用POST,限定GET固然POST并非十拿九稳,进击者只需组织一个form就能够,但须要在第三方页面做,如许就增添暴露的可能性。

2.在阻拦客户端阻拦器加token增加 token 并考证,能够加到参数中,或许在 HTTP 头中自定义属性并考证。
3.考证 HTTP Referer 字段,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 要求的泉源地点。

请细致说下你对 Vue 生命周期的明白?

统共分为 8 个阶段竖立前/后,载入前/后,更新前/后,烧毁前/后。

  1. 竖立前/后: 在 beforeCreate 阶段,vue 实例的挂载元素 el 还没有。
  2. 载入前/后:在 beforeMount 阶段,vue 实例的$el 和 data 都初始化了,但照样挂载之前为假造的 dom 节点,data.message 还未替代。在 mounted 阶段,vue 实例挂载完成,data.message 胜利衬着。
  3. 更新前/后:当 data 变化时,会触发 beforeUpdate 和 updated 要领。
  4. 烧毁前/后:在实行 destroy 要领后,对 data 的转变不会再触发周期函数,申明此时 vue 实例已消除了事宜监听以及和 dom 的绑定,然则 dom 构造依旧存在

四种罕见的 POST 提交数据体式格局对应的content-type取值

application/x-www-form-urlencoded —— 阅读器的原生 form 表单
multipart/form-data —— 表单上传文件时,必需让 form 的 enctyped 等于这个值
application/json —— 用来通知服务端音讯主体是序列化后的 JSON 字符串
text/xml —— HTTP 作为传输协定,XML 作为编码体式格局的长途挪用范例

computed道理

  1. 当组件初始化的时刻,computed 和 data 会离别竖立各自的相应体系,Observer遍历 data 中每一个属性设置 get/set 数据阻拦
  2. 初始化 computed 会挪用 initComputed 函数
    (1)注册一个 watcher 实例,并在内实例化一个 Dep 音讯定阅器用作后续网络依靠(比方衬着函数的 watcher 或许其他视察该盘算属性变化的 watcher)
    (2)挪用盘算属性时会触发其Object.defineProperty的get接见器函数
    (3)挪用 watcher.depend() 要领向本身的音讯定阅器 dep 的 subs 中增加其他属性的 watcher
    (4) 挪用 watcher 的 evaluate 要领(进而挪用 watcher 的 get 要领)让本身成为其他 watcher 的音讯定阅器的定阅者,首先将 watcher 赋给 Dep.target,然后实行 getter 求值函数,当接见求值函数内里的属性(比方来自 data、props 或其他 computed)时,会一样触发它们的 get 接见器函数从而将该盘算属性的 watcher 增加到求值函数中属性的 watcher 的音讯定阅器 dep 中,当这些操纵完成,末了封闭 Dep.target 赋为 null 并返回求值函数效果。
  3. 当某个属性发生变化,触发 set 阻拦函数,然后挪用本身音讯定阅器 dep 的 notify 要领,遍历当前 dep 中保存着一切定阅者 wathcer 的 subs 数组,并逐一挪用 watcher 的 update 要领,完成相应更新。

computed 和 watch 的差别:

  1. computed 是盘算一个新的属性,并将该属性挂载到 vm(Vue 实例)上,而 watch 是监听已存在且已挂载到 vm上的数据,所以用 watch 一样能够监听 computed 盘算属性的变化(别的另有 data、props)
  2. computed 实质是一个惰性求值的视察者,具有缓存性,只需当依靠变化后,第一次接见computed 属性,才会盘算新的值,而 watch 则是当数据发生变化便会挪用实行函数
  3. 从运用场景上说,computed实用一个数据被多个数据影响,而 watch 实用一个数据影响多个数据;

CSS3

    @keyframes rotating{
        from{transform:rotate(0)}
        to{transform:rotate(360deg)}
    }
    animation:rotating 1.2s linear infinite;

寄生组合继续

    function Person(name){
     this.name=name; //1
     this.className="person" 
    }
    Person.prototype.getName=function(){
     console.log(this.name)
    }
    function Man(name){
      Person.apply(this,arguments)
    }
    //注重此处
    Man.prototype = Object.create(Person.prototype);
    var man1=new Man("Davin");
    > man1.name
    >"Davin"
    > man1.getName()
    >"Davin"

ES6中的class和ES5的类有什么区分?

1.ES6 class 内部一切定义的要领都是不可罗列的;
2.ES6 class 必需运用 new 挪用;
3.ES6 class 不存在变量提拔;
4.ES6 class 默许等于严厉形式;
5.ES6 class 子类必需在父类的组织函数中挪用super(),如许才有this对象;ES5中类继续的关联是相反的,先有子类的this,然后用父类的要领应用在this上。

let、const 以及 var 的区分是什么?

1.let 和 const 定义的变量不会涌现变量提拔,而 var 定义的变量会提拔。
2.let 和 const 是JS中的块级作用域
3.let 和 const 不允许反复声明(会抛出毛病)
4.let 和 const 定义的变量在定义语句之前,假如运用会抛出毛病(形成了暂时性死区),而 var 不会。
5.const 声明一个只读的常量。一旦声明,常量的值就不能转变(假如声明是一个对象,那末不能转变的是对象的援用地点)

在JS中什么是变量提拔?什么是暂时性死区?

变量提拔就是变量在声明之前就能够运用,值为undefined。在代码块内,运用 let/const 敕令声明变量之前,该变量都是不可用的(会抛出毛病)。这在语法上,称为“暂时性死区”。暂时性死区也意味着 typeof 不再是一个百分百平安的操纵。

typeof x;
// ReferenceError(暂时性死区,抛错)
let x;
typeof y;
// 值是undefined,不会报错

HTML中的meta标签经常使用属性及其作用总结

charset: 声明字符编码

<meta charset="utf-8"> //HTML5

http-equiv:

模拟http标头字段
http-equiv属性与content属性连系运用, http-equiv属性为指定所要模拟的标头字段的称号,content属性用来供应值。
refresh 指定一个时刻距离(以秒为单元),在此时刻过去以后从服务器从新载入当前页面,也能够别的指定一个页面.
<meta http-equiv="refresh" content="2;URL=http://www.baidu.com">

name 和 content:

<meta name="参数" content="详细形貌信息">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
重要引见一个当meta标签的name属性值为viewreport时的视口的大小
name属性与content属性连系运用, name用来示意元数据的范例,示意当前<meta>标签的详细作用;content属性用来供应值

什么是闭包?闭包的作用是什么?闭包有哪些运用场景?

闭包是指有权接见另一个函数作用域中的变量的函数,竖立闭包最经常使用的体式格局就是在一个函数内部竖立另一个函数。
闭包的作用有:
1.封装私有变量
2.模拟块级作用域(ES5中没有块级作用域)
3.完成JS的模块

CSS中你晓得的display的值有若干?

none:隐蔽对象。与visibility属性的hidden值差别,其不为被隐蔽的对象保存其物理空间
inline:指定对象为内联元素。
block:指定对象为块元素。
list-item:指定对象为列表项目。
inline-block:指定对象为内联块元素。(CSS2)
table:指定对象作为块元素级的表格。类同于html标签<table>(CSS2)
inline-table:指定对象作为内联元素级的表格。类同于html标签<table>(CSS2)
flex:将对象作为弹性伸缩盒显现。(伸缩盒最新版本)(CSS3)
table-cell:指定对象作为表格单元格。类同于html标签<td>(CSS2)

    原文作者:李帅醒
    原文地址: https://segmentfault.com/a/1190000019150338
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞