前端常见问题01

1、对象的扩展方法

  • keys:数组类型,获取对象的键
  • values:数组类型,获取对象的值
  • entries:返回多个数组,每个数组包含对象的索引、值
  • freeze:冻结对象,指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性

2、原型链

基本使用:
'use strict';
const obj = {
    age: 20,
    name: "zhangsan"
}
// 往对象的原型链中添加方法
obj.__proto__.$once = () => {
    console.log("aaaaA");
}
obj.$once(); // aaaaA
/* ------------------ */
function func(){}
func.prototype.$once = () => {
    console.log("this is function prototype");
}

// new 的实际原理
const p = {};
p.__proto__ = func.prototype
p.$once(); // this is function prototype

const q = new func();
console.log(q.__proto__ === func.prototype); // true

obj.__proto__ = func.prototype
obj.$once(); // this is function prototype

3、执行上下文及其生命周期

生命周期:

1、创建:生成变量对象,建立作用域链,确定this指向。

2、执行:变量赋值,函数引用,执行其他代码

3、执行完毕,出栈,等待回收

4、闭包的实际作用

function checkscoped(){
    var scope = 0;
    return function(){
        return ++scope;
    }
}
// 赋给 add 的实际上是return 的方法,其余部分只调用了一次
const add = checkscoped();

console.log(add()); // 1
console.log(add()); // 2
console.log(add()); // 3

5、深浅拷贝

6、position:sticky

  • 粘性定位

  • 依赖于用户的滚动,在 position:relativeposition:fixed 定位之间切换。

    position: -webkit-sticky; /* Safari */
    position: sticky;
    

7、虚拟DOM

  • 在之前的 mounted 方法的实现中,会把 template 编译成 render 方法。在 Vue 的 mount 过程中,template 会被编译成 AST 语法树,AST 是指抽象语法树(abstract syntax tree 或者缩写为 AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式。

8、GET与POST的区别

分类GETPOST
后退/刷新数据重新提交
书签能收藏为书签不能收藏为书签
缓存能被缓存不能被缓存
历史参数保留在历史中参数不保留
长度限制2048个字符无限制
数据类型ASCII字符没有限制
安全性较差较安全
数据可见性数据暴露在地址栏中数据通过调试模式/其他工具查看

9、函数式编程

  • 纯函数,非纯函数

    纯函数在运行过程中不影响运行环境,无副作用。

    非纯函数在运行过程中会修改相关的数据环境。

    /* -- 纯函数 不会修改arr -- */
    let arr = [1,2,3,4,5,6];
    arr.slice(0,3); // 1 ,2 ,3
    arr.slice(0,3); // 1 ,2 ,3
    /* -- 非纯函数 会修改arr -- */
    arr.splice(0,3); // 1, 2, 3
    arr.splice(0,3); // 4, 5, 6
    

10、什么是柯里化

  • 就是把一个多参数的函数转化为单参数的函数的方法
function add(a , b){ return a+b;} // add(1,2)
/* --- 转化为 --- */
function add(a){
    return function(b){
        return a + b;
    }
}
// add(1)(2);
  • 作用:

    1. 利用了闭包,能够实现参数的复用

      function add(a){
          return function(b){
              return a + b;
          }
      }
      let p = add(1); // 保留了参数 1 , 每次调用 p 都只加 1
      p(2); // 3
      p(3); // 4
      
    2. 提前确定

    3. 延迟运行

11、事件循环 Event Loop

  • 运行机制:
    1. 所有同步任务都在主线程上执行,形成一个执行栈。
    2. 主线程之外还存在一个 任务队列 ,存放待执行的任务
    3. 当 执行栈 中的所有同步任务执行完毕,系统就会读取任务队列,按顺序将任务提取到执行栈中,执行。
    4. 重复上述步骤 3

12、作用域链

const a = 1;
function func(){
	let b = 1;
    while(b){
        console.log(a);
        --b;
    }
}
  • 如上代码,console.log 要获取变量 a 的值,当当前 while 作用域中并没有定义 a 变量(当前作用域没有定义的变量成为 自由变量),于是,向父级作用域——func 查找,但是 func 函数作用域内也没有 a 变量,再继续往父级作用域——全局作用域寻找。(如果全局作用域还是没找到的话即报错)

13、Promise

  • 是异步编程的一种解决方案。用于避免回调地狱,其也能更好的进行错误捕获。

  • 状态:

    • 等待态:pending - 执行过程
    • 成功态:fulfiled - 异步操作成功
    • 失败态:rejected - 异步操作失败
  • 参数:

    • resolve:异步操作成功的回调
    • reject:异步操作失败的回调
  • 回调:

    • then:对应 resolve
    • catch:对应 reject
    new Promise(function(resolve , reject){
    	resolve(data);
        // reject(data);
    })
    .then( res => {})
    .ctach( err => {})
    
  • 缺点:

    1. 无法取消,一旦新建就会立即执行,中途不能停止。
    2. 无法追踪,当处于 pending 状态时,无法得知当前的运行阶段。(开始/完成)
    3. 没有设置回调时,抛出的错误无法被外部获取。

14、事件的发布订阅

  • 相当于将发布者与订阅者分开,订阅者将方法逻辑存放在调度中心,等待有人调用时才触发该方法。
class bus {
    constructor(){
        this._funcArray = [];
        this._callbackArray = [];
    }
    // 插入到方法队列中
    $on(funcName , callback){
        // 判断回填函数是否是方法
        if(typeof callback !== "function")
            throw new Error(`${funcName}的回调需要为函数类型`);
        this._funcArray.push(funcName);
        this._callbackArray.push(callback);
    }
    // 删除方法队列的相应方法
    $off(funcName){
        if(this._funcArray.indexOf(funcName) <= -1){
            throw new Error(`不存在该方法`);
        }
        let index = this._funcArray.indexOf(funcName);
        this._funcArray.splice(index , 1);
        this._callbackArray.splice(index , 1);
    }
    // 触发方法队列的特定位置方法
    $emit(funcName , ...data) {
        if(this._funcArray.indexOf(funcName) <= -1){
            throw new Error(`不存在该方法`);
        }
        // 校验数组的长度
        if( !this._funcArray.length && 
           	!this._callbackArray.length && 
           	this._funcArray.length !== this._callbackArray.length 
          ){
            throw new Error(`error occur!`)
        }
        let index = this._funcArray.indexOf(funcName);
        /* 数据长度: 唯一  大于一 */
        if(data.length > 1)
        	this._callbackArray[index](data);
		else if(data.length <= 1)
        	this._callbackArray[index](data.pop());
    }
}

15、宏任务与微任务的区别

  • 宏任务:当前执行栈中运行的代码即为宏任务。(主代码块,定时器,I/O等)

  • 微任务:相当于回调事件。(promise 的回调)

  • 运行过程:

    宏任务运行结束之后,会查找是否有可执行的微任务,有的话将执行所有微任务,执行结束开始执行新的宏任务;没有的话将开始新的宏任务。

参考文章:

1、都9102年了,还问GET和POST的区别

2、JavaScript 运行机制详解:再谈Event Loop

3、JS的发布订阅模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值