• 前端知识点


    目录

    js中new一个对象的过程

    使用new关键字调用函数(new ClassA(…))的具体步骤:
    
    1. 创建空对象;
    var obj = {};
    
    2. 设置新对象的constructor属性为构造函数的名称,设置新对象的__proto__属性指向构造函数的prototype对象;
    obj.__proto__ = ClassA.prototype;
    
    3. 使用新对象调用函数,函数中的this被指向新实例对象:
    ClassA.call(obj);  //{}.构造函数();          
    
    4. 将初始化完毕的新对象地址,保存到等号左边的变量中
    

    什么是闭包?闭包的优缺点

    答:闭包是将外部作用域中的局部变量封闭起来的函数对象。被封闭起来的变量与封闭它的函数对象有相同的生命周期。

    优点:一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。

    缺点:

    • 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
    • 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    什么是盒子模型?CSS-标准盒模型和怪异盒模型的区别?哪个css可以改变盒子模型?

    css盒子模型 又称为框模型(Box Model),包含了元素内容(content)、内边距(padding)、边框(border)、外边距(margin)几个要素。

    标准盒模型
    avatar
    怪异盒模型
    avatar
    区别:当不对doctype进行定义时,会触发怪异模式。

    • 在标准模式下,一个块的总宽度= width + margin(左右) + padding(左右) + border(左右)
    • 在怪异模式下,一个块的总宽度= width + margin(左右)(即width已经包含了padding和border值)

    display取值,元素默认是什么,内联元素块级元素可变元素有哪些?img是什么?

    img是内联元素

    display CSS属性指定用于元素的呈现框的类型。在 HTML 中,默认的 display 属性取决于 HTML 规范所描述的行为或浏览器/用户的默认样式表。

    默认值是inline
    display取值如下:

    none	此元素不会被显示。
    block	此元素将显示为块级元素,此元素前后会带有换行符。
    inline	默认。此元素会被显示为内联元素,元素前后没有换行符。
    inline-block	行内块元素。(CSS2.1 新增的值)
    list-item	此元素会作为列表显示。
    run-in	此元素会根据上下文作为块级元素或内联元素显示。
    compact	CSS 中有值 compact,不过由于缺乏广泛支持,已经从 CSS2.1 中删除。
    marker	CSS 中有值 marker,不过由于缺乏广泛支持,已经从 CSS2.1 中删除。
    table	此元素会作为块级表格来显示(类似 <table>),表格前后带有换行符。
    inline-table	此元素会作为内联表格来显示(类似 <table>),表格前后没有换行符。
    table-row-group	此元素会作为一个或多个行的分组来显示(类似 <tbody>)。
    table-header-group	此元素会作为一个或多个行的分组来显示(类似 <thead>)。
    table-footer-group	此元素会作为一个或多个行的分组来显示(类似 <tfoot>)。
    table-row	此元素会作为一个表格行显示(类似 <tr>)。
    table-column-group	此元素会作为一个或多个列的分组来显示(类似 <colgroup>)。
    table-column	此元素会作为一个单元格列显示(类似 <col>)
    table-cell	此元素会作为一个表格单元格显示(类似 <td> 和 <th>)
    table-caption	此元素会作为一个表格标题显示(类似 <caption>)
    inherit	规定应该从父元素继承 display 属性的值。
    

    float:left情况下是怎样的,此时如果超出了宽度范围

    该元素从网页的正常流动中移除,尽管仍然保持部分的流动性
    css3的transform

    CSS transform 属性允许你修改CSS视觉格式模型的坐标空间。使用它,元素可以被转换(translate)、旋转(rotate)、缩放(scale)、倾斜(skew)。

    输入一个URL后会发生什么?

    总体来说分为以下几个过程:

    • DNS解析
    • TCP连接
    • 发送HTTP请求
    • 服务器处理请求并返回HTTP报文
    • 浏览器解析渲染页面
    • 连接结束

    tcp 协议,http协议
    hit-alibaba.github.io/interview/b…

    tcp协议即是传输控制协议,

    http协议:

    HTTP构建于TCP/IP协议之上,默认端口号是80 HTTP是无连接无状态的

    写一个继承函数

    function Parent() {
      this.property = true
    }
    Parent.prototype.getParentValue = function () {
      return this.property
    }
    function Child() {
      this.Childproperty = false
    }
    Child.prototype = new Parent()
    Child.prototype.getChildValue = function () {
      return this.Childproperty
    }
    var instance = new Child()
    console.log(instance.getParentValue()) // true
    

    写一个快速排序

    "快速排序"的思想很简单,整个排序过程只需要三步:

    (1)在数据集之中,选择一个元素作为"基准"(pivot)。
    
    (2)所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
    
    (3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
    
    function quickSort(arr) {
      if(arr.length < 2) {
        return arr;
      } else {
        const pivot = arr[0]; // 基准值
        const pivotArr = []; // 一样大的放中间
        const lowArr= []; // 小的放左边
        const hightArr = []; // 大的放右边
        arr.forEach(current => {
          if(current === pivot) pivotArr.push(current);
          else if(current > pivot) hightArr.push(current);
          else lowArr.push(current);
        })
        return quickSort(lowArr).concat(pivotArr).concat(quickSort(hightArr));
      }
    }
    

    写一个js判断全等的方法

    //利用JSON.stringify,将两个对象转化为字符串。
    字符串相等的话,说明两个对象全等。
    let a = {a:0,b:1,c:2};
    let b = {a:0,b:1,c:2};
    let c = {a:1,b:1,c:2};
    let x = JSON.stringify(a) == JSON.stringify(b);
    let y = JSON.stringify(a) == JSON.stringify(c);
    console.log(x);
    console.log(y);
    

    遍历对象的方法

    var obj={a:'A',b:'B',c:'C'};
    
    1. for ... in 循环
    for(key in obj){
        console.log(key);// a,b,c
    }
    
    2. Object.keys()
    Object.keys(obj);//["a", "b", "c"]
    

    防抖和节流

    1. 防抖

    触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

    思路

    每次触发事件时都取消之前的延时调用方法

    function debounce(fn) {
          let timeout = null; // 创建一个标记用来存放定时器的返回值
          return function () {
            clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
            timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
              fn.apply(this, arguments);
            }, 500);
          };
        }
        function sayHi() {
          console.log('防抖成功');
        }
    
        var inp = document.getElementById('inp');
        inp.addEventListener('input', debounce(sayHi)); // 防抖
    
    1. 节流

    高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

    思路

    每次触发事件时都判断当前是否有等待执行的延时函数

    function throttle(fn) {
          let canRun = true; // 通过闭包保存一个标记
          return function () {
            if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
            canRun = false; // 立即设置为false
            setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
              fn.apply(this, arguments);
              // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
              canRun = true;
            }, 500);
          };
        }
        function sayHi(e) {
          console.log(e.target.innerWidth, e.target.innerHeight);
        }
        window.addEventListener('resize', throttle(sayHi));
    

    问题

    为什么要 fn.apply(this, arguments);而不是这样 fn()

    答:加上 apply 确保 在 sayHi 函数里的 this 指向的是 input对象(不然就指向 window 了,不是我们想要的)。 这里的箭头函数依旧是指向 input 对象。

    https怎么保证安全的? 什么情况下会碰到跨域问题?有哪些解决方法?

    • 跨域问题是这是浏览器为了安全实施的同源策略导致的,同源策略限制了来自不同源的document、脚本,同源的意思就是两个URL的域名、协议、端口要完全相同。
    • script标签jsonp跨域、nginx反向代理、node.js中间件代理跨域、后端在头部信息设置安全域名、后端在服务器上设置cors。

    如何判断一个变量是对象还是数组?

    function isObjArr(value){
         if (Object.prototype.toString.call(value) === "[object Array]") {
                console.log('value是数组');
           }else if(Object.prototype.toString.call(value)==='[object Object]'){//这个方法兼容性好一点
                console.log('value是对象');
          }else{
              console.log('value不是数组也不是对象')
          }
    }
    //ps:千万不能使用typeof来判断对象和数组,因为这两种类型都会返回"object"。
    

    事件循环机制

    html事件循环:
    一个浏览器环境,只能有一个事件循环,而一个事件循环可以多个任务队列(task queue),每个任务都有一个任务源(task source)。
    
    相同任务源的任务,只能放到一个任务队列中。
    
    不同任务源的任务,可以放到不同任务队列中。
    
    EcmaScript规范中指出:
    任务队列(Job queue)是一个先进先出的队列,每一个任务队列是有名字的,至于有多少个任务队列,取决于实现。每一个实现至少应该包含以上两个任务队列。
    
    结论:EcmaScript的Job queue与HTML的Task queue有异曲同工之妙。它们都可以有好几个,多个任务队列之间的顺序都是不保证的。
    
    例子:
    setImmediate(function(){ 
       console.log(1); 
    },0); 
    
    setTimeout(function(){ 
       console.log(2); 
    },0);
    
    new Promise(function(resolve){ 
        console.log(3); 
        resolve(); 
        console.log(4); 
    }).then(function(){
        console.log(5); 
    }); 
    
    console.log(6); 
    
    process.nextTick(function(){ 
        console.log(7); 
    }); 
    
    console.log(8);
    
    结果:3 4 6 8 7 5 2 1
    
    事件注册顺序如下:
    setImmediate - setTimeout - promise.then - process.nextTick
    
    优先级关系:
    process.nextTick > promise.then > setTimeout > setImmediate
    
    V8实现中,两个队列各包含不同的任务:
    macrotasks(宏任务): script(整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering
    microtasks(微任务): process.nextTick, Promises, Object.observe, MutationObserver
    
    执行过程如下:
    js引擎首先从macrotask queue中取出第一个任务,执行完毕后,将microtask queue中的所有任务取出,按顺序全部执行;然后再从macrotask queue中取下一个,执行完毕后,再次将microtask queue中的全部取出; 循环往复,直到两个queue中的任务都取完。
    
    setTimeout会默认延迟4毫秒(ms)。
    
    问题:
    process.nextTick也会放入microtask quque,为什么优先级比promise.then高呢?
    
    答:process.nextTick 永远大于promise.then,原因其实很简单。
    在Node中,_tickCallback在每一次执行完TaskQueue中的一个任务后被调用,而这个_tickCallback中实质上干了两件事:
    1. nextTickQueue中所有任务执行掉(长度最大1e4,Node版本v6.9.1)
    2. 第一步执行完后执行_runMicrotasks函数,执行microtask中的部分(promise.then注册的回调)
    所以很明显process.nextTick > promise.then
    
    

    深拷贝和浅拷贝

    区别

    1. 浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用

    2. 深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

    为什么要使用深拷贝?
    我们希望在改变新的数组(对象)的时候,不改变原数组(对象)

    深拷贝的要求程度

    我们在使用深拷贝的时候,一定要弄清楚我们对深拷贝的要求程度:是仅“深”拷贝第一层级的对象属性或数组元素,还是递归拷贝所有层级的对象属性和数组元素?

    怎么检验深拷贝成功
    改变任意一个新对象/数组中的属性/元素, 都不改变原对象/数组

    只做第一层深拷贝

    深拷贝数组(只拷贝第一级数组元素)

    1. 直接遍历
    var arr = [1,2,3,4];
    
    
    function copy(arg){
      
      var newArr = [];
      
      for(var i = 0; i < arr.length; i++) {
        newArr.push(arr[i]);
      }
      
      return newArr;
    }
    
    var newArry = copy(arr);
    console.log(newArry);
    newArry[0] = 10;
    console.log(newArry); // [10,2,3,4]
    console.log(arr)  // [1,2,3,4]
    
    1. slice()
    var arr = [1,2,3,4]
    var copyArr = arr.slice();
    copyArr[0] = 10;
    console.log(copyArr); // [10,2,3,4]
    console.log(arr); // [1,2,3,4]
    
    // slice() 方法返回一个从已有的数组中截取一部分元素片段组成的新数组(不改变原来的数组!)
    用法:array.slice(start,end) start表示是起始元素的下标, end表示的是终止元素的下标
    当slice()不带任何参数的时候,默认返回一个长度和原数组相同的新数组
    
    
    1. concat()
    var arr = [1,2,3,4]
    var copyArr = arr.concat();
    copyArr[0] = 10;
    console.log(copyArr); // [10,2,3,4]
    console.log(arr); // [1,2,3,4]
    
    //concat() 方法用于连接两个或多个数组。( 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。)
    用法:array.concat(array1,array2,......,arrayN)
    因为我们上面调用concat的时候没有带上参数,所以var copyArray = array.concat();实际上相当于var copyArray = array.concat([]);
    也即把返回数组和一个空数组合并后返回
    

    深拷贝对象

    1. 直接遍历
     var obj = {
        name: "张三",
        job: "学生"
      }
      
      function copy (obj) {
        let newobj = {}
        for(let item in obj) {
          newobj[item] = obj[item];
        }
        return newobj;
      }
      
      var copyobj = copy(obj)
      copyobj.name = "李四"
      console.log(copyobj) // {name: '李四', job:: '学生'}
      console.log(obj) // {name: '张三', job:: '学生'}
    
    
    1. ES6的Object.assign
    var obj = {
     name: '张三',
     job: '学生'
    }
    
    var copyobj = Object.assign({},obj)
    copyobj.name = '李四'
    console.log(copyobj) // {name: '李四', job:: '学生'}
    console.log(obj)    // {name: '张三', job:: '学生'}
    
    Object.assign:用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),并返回合并后的target
    用法: Object.assign(target, source1, source2);  所以 copyObj = Object.assign({}, obj);  这段代码将会把obj中的一级属性都拷贝到 {}中,然后将其返回赋给copyObj
    
    1. ES6扩展运算符:
    var obj = {
      name: '张三',
      job: '学生'
    }
    
    var copyobj = {...obj}
    copyobj.name = '李四'
    console.log(copyobj)
    console.log(obj)
    
    扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
    

    ajax请求

    // 1.XMLHttpRequest对象用于在后台与服务器交换数据   
    var xhr = new XMLHttpRequest();
    // 2.
    xhr.open('GET', url, true);
    //3.发送请求
    xhr.send();
    //4.接收返回
    //客户端和服务器端有交互的时候会调用onreadystatechange
    xhr.onreadystatechange = function() {
        // readyState == 4说明请求已完成
        if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) { 
            // 从服务器获得数据 
            fn.call(this, xhr.responseText);  
        }
    };
    
  • 相关阅读:
    修改采购订单项目的内容显示、更改
    100小时学会sap傻瓜式入门版财务篇之co篇
    100小时学会sap傻瓜式入门版销售与分销sd篇
    100小时学会sap傻瓜式入门版生产计划pp篇
    ABAP SYNTAX COLLECTION II
    100小时学会sap傻瓜式入门版物料管理mm篇
    【转】systemconfigkickstart Package selection is disabled due to problems
    【转】如何在同一台机器上配置多个jboss应用服务器实例(以jboss4.0.5为标准)
    Windows7 install jeklly
    【转】VBoxManage命令详解
  • 原文地址:https://www.cnblogs.com/dobeco/p/11295320.html
Copyright © 2020-2023  润新知