前端整理知识点

作者:AmbitionC
链接:https://www.nowcoder.com/discuss/258810?type=2&order=0&pos=3&page=2
来源:牛客网

一、JavaScript

  1. 原始值和引用值类型及区别
  2. 判断数据类型typeof、instanceof、Object.prototype.toString.call()、constructor
  3. 类数组与数组的区别与转换
1. 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理);
2. 不具有数组所具有的方法;
3. 类数组是一个普通对象,而真实的数组是Array类型。

常见的类数组包括: arguments、nodeList、HTMLCollection、、

转换:
1. Array.prototype.slice.call(arraylike)
2. [...arraylike]
3. Array.from()
  1. 数组的常见API
1. 改变原数组:
push()、pop(), shift()、unshift()、reverse()、sort()、splice()
2. 不改变原数组:
concat()、slice()、toString()、join()
3.map()与forEach区别
能用forEach()做到的,map()同样可以。反过来也是如此。
map()会分配内存空间存储新数组并返回,forEach()不会返回数据。
forEach()允许callback更改原始数组的元素。map()返回新的数组。
  1. bind、call、apply的区别
同: 改变this指针
异: 1. call、apply调用时会立即执行,而bind会返回一个函数
    2. call、bind穿参为arg1,arg2,arg3...;而apply传参为一个数组
实现:
// fn.call(obj, name,age)
Function.prototype.call2 = function(context){
    context = context || 'window';
    context.fn = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var result = context.fn(args);
    delete context.fn;
    return result;
}
// fn.apply(obj, [age, name]);
Function.prototype.apply2 = function(context){
    context = context || 'window';
    context.fn = this;
    var result;
    if(arguments[1]){
        result = context.fn(arguments[1])
    }else{
        result = context.fn();
    }
    delete context.fn;
    return result;
}
// var f = fn.bind(obj); f(age, name);
Function.prototype.bind2 = function(context){
    var fn = this;
    var context = context || 'window';
    var resFn =  function(){
        var args = Array.prototype.slice.call(arguments);
        return fn.apply(this instenceof resFn ? context : window, args);
    }
    function temp(){}
    temp.prototype = fn.prorotype;
    resFn.prototype = new temp();
    return resFn;
}
  1. new的原理
function New(fn){
    var obj = new Object();
    obj.prototype = obj.prototype;
    var result = fn.call(obj);
    return typeof result == 'object' ? result : obj;
}
  1. 如何正确判断this?
1. 什么是this?  this指向是在运行时基于函数的执行环境绑定的,即在函数调用的时候发生绑定

2. 如何判断this绑定的对象?

    1. 作为对象调用形式,谁最终调用了函数, 那么他就是this的绑定对象,在全局下调用,那么this绑定在全局对象上
    2. 使用call\bind\apply改变this指向, 一般函数调用fn() == fn.call() == fn.call(undefined), 在非严格模式下, 默认为window。
    3. new。new调用,this绑定到新创建的对象,且无法通过其它方式改变this绑定的对象。
    4. 箭头函数和定时器。箭头函数的this始终指向外层上下文环境,不能通过bind\apply\call改变this指向。定时器,由于定时器的执行环境和所在函数完全分离,所以定时器在肺炎个模式下this指向window, 可以通过call\apply\bind改变this的指向。
    5. 优先级:new绑定--显示绑定(call\apply\bind)--隐式绑定(对象调用)--默认绑定
  1. 闭包及其作用

  2. 原型和原型链

  3. prototype与proto的关系与区别

  4. 继承的实现方式及比较

六种方式:
1. 原型链继承
实现: 将父类实例作为子类原型
缺点:继承比较单一,只能继承自一个超类
     不能向构造函数穿参
     所有子类继承自一个父类实例,存在引用类型值修改会相互影响的问题

2. 借用构造函数
实现:使用父类构造函数来增强子类实例
优点:可以实现多继承,可向构造函数穿参, 不存在子类实例共享引用属性的问题
缺点:实例并不是父类的实例(instanceof),只是子类实例
     并不能实现真正的函数继承,每个子类实例都有父类实例函数方法的副本
     只能继承父类的实例属性和方法, 不能继承原型上的属性和方法。
3. 组合继承
特点: 可继承实例属性/方法,也可以继承原型上的属性/方法
      实现多继承
      可穿参
      即是子类的实例,也是父类的实例
      函数可复用
      不存在应用属性共享问题
缺点:调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的实例覆盖了)
4. 原型式继承
实现:继承已有对象而不是函数
特点: 没有必要创建构造函数,只是想让一个对象与另一个对象相似
      引用类型属性值会共享
5. 寄生式继承 
实现: 在原型式继承外包装一层,可以添加新的属性和方法
缺点: 应用类型属性共享
6. 寄生组合继承
实现: 使用寄生式继承继承父类原型, 在使用构造函数,继承实例属性和方法
缺点: 实现较为复杂
  1. 深拷贝与浅拷贝

```
13. 防抖和节流
14. 作用域和作用域链、执行期上下文
15. DOM常见的操作方式
16. Array.sort()方法与实现机制
17. Ajax的请求过程
18. JS的垃圾回收机制
19. JS中的String、Array和Math方法
20. addEventListener和onClick()的区别
21. new和Object.create的区别
22. DOM的location对象
23. 浏览器从输入URL到页面渲染的整个流程(涉及到计算机网络数据传输过程、浏览器解析渲染过程)
24. 跨域、同源策略及跨域实现方式和原理
25. 浏览器的回流(Reflow)和重绘(Repaints)
26. JavaScript中的arguments
27. EventLoop事件循环
28. 宏任务与微任务
29. BOM属性对象方法
30. 函数柯里化及其通用封***r>31. JS的map()和reduce()方法
32. “==”和“===”的区别
33. setTimeout用作倒计时为何会产生误差?

全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务