前端基础-js2

2.11 dva的数据流流向是怎么样的

参考答案:

​ 数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据 的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是 异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State,所以在 dva 中,数据流向非 常清晰简明,并且思路基本跟开源社区保持一致。

2.12 变量提升

参考答案:

JavaScript是单线程语言,所以执行肯定是按顺序执行。但是并不是逐行的分析和执行,而是一段一段地分析执行,会先进行编译阶段然后才是执行阶段。在编译阶段阶段,代码真正执行前的几毫秒,会检测到所有的变量和函数声明,所有这些函数和变量声明都被添加到名为Lexical Environment的JavaScript数据结构内的内存中。所以这些变量和函数能在它们真正被声明之前使用。

2.13 作用域

参考答案:

概念:作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。

ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。

扩展:

var ——ES5 变量声明方式

  1. 在变量未赋值时,变量undefined(为使用声明变量时也为undefined)
  2. 作用域——var的作用域为方法作用域;只要在方法内定义了,整个方法内的定义变量后的代码都可以使用

let——ES6变量声明方式

  1. 在变量为声明前直接使用会报错
  2. 作用域——let为块作用域——通常let比var 范围要小
  3. let禁止重复声明变量,否则会报错;var可以重复声明

const——ES6变量声明方式

​ const为常量声明方式;声明变量时必须初始化,在后面出现的代码中不能再修改该常量的值

​ const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动

2.14 HashMap 和 Array 有什么区别?

参考答案:

  1. 查找效率
    HashMap因为其根据hashcode的值直接算出index,所以其查找效率是随着数组长度增大而增加的。
    ArrayMap使用的是二分法查找,所以当数组长度每增加一倍时,就需要多进行一次判断,效率下降

  2. 扩容数量
    HashMap初始值16个长度,每次扩容的时候,直接申请双倍的数组空间。
    ArrayMap每次扩容的时候,如果size长度大于8时申请size*1.5个长度,大于4小于8时申请8个,小于4时申 请4个。这样比较ArrayMap其实是申请了更少的内存空间,但是扩容的频率会更高。因此,如果数据量比较大的时候,还是使用HashMap更合适,因为其扩容的次数要比ArrayMap少很多。

  3. 扩容效率
    HashMap每次扩容的时候重新计算每个数组成员的位置,然后放到新的位置。
    ArrayMap则是直接使用System.arraycopy,所以效率上肯定是ArrayMap更占优势。

  4. 内存消耗
    以ArrayMap采用了一种独特的方式,能够重复的利用因为数据扩容而遗留下来的数组空间,方便下一个ArrayMap的使用。而HashMap没有这种设计。 由于ArrayMap之缓存了长度是4和8的时候,所以如果频繁的使用到Map,而且数据量都比较小的时候,ArrayMap无疑是相当的是节省内存的。

总结
综上所述,数据量比较小,并且需要频繁的使用Map存储数据的时候,推荐使用ArrayMap。 而数据量比较大的 时候,则推荐使用HashMap。

2.15 HashMap和Object

参考答案:

ObjectsMaps 类似的是,它们都允许你按键存取一个值、删除键、检测一个键是否绑定了值。因此(并且也没有其他内建的替代方式了)过去我们一直都把对象当成 Maps 使用。不过 MapsObjects 有一些重要的区别,在下列情况里使用 Map 会是更好的选择:

Map Object
意外的键 Map 默认情况不包含任何键。只包含显式插入的键。 一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。注意: 虽然 ES5 开始可以用 Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。
键的类型 一个 Map的键可以是任意值,包括函数、对象或任意基本类型。 一个Object 的键必须是一个 String 或是Symbol
键的顺序 Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 一个 Object 的键是无序的注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
Size Map 的键值对个数可以轻易地通过size 属性获取 Object 的键值对个数只能手动计算
迭代 Mapiterable 的,所以可以直接被迭代。 迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能 在频繁增删键值对的场景下表现更好。 在频繁添加和删除键值对的场景下未作出优化。

2.16 javascript中arguments相关的问题

参考答案:

arguments

在js中,我们在调用有参数的函数时,当往这个调用的有参函数传参时,js会把所传的参数全部存到一个叫arguments的对象里面。它是一个类数组数据

由来

Javascrip中每个函数都会有一个Arguments对象实例arguments,引用着函数的实参。它是寄生在js函数当中的,不能显式创建,arguments对象只有函数开始时才可用

作用

有了arguments这个对象之后,我们可以不用给函数预先设定形参了,可以动态地通过arguments为函数加入参数

2.17 instanceOf 原理,手动实现 function isInstanceOf (child, Parent)

参考答案

instanceof主要作用就是判断一个实例是否属于某种类型

let person = function(){

}
let no = new person()
no instanceof person//true

instanceOf 原理

function new_instance_of(leftVaule, rightVaule) { 
    let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
    leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
    while (true) {
        if (leftVaule === null) {
            return false;    
        }
        if (leftVaule === rightProto) {
            return true;    
        } 
        leftVaule = leftVaule.__proto__ 
    }
}

其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。

同时还要了解js的原型继承原理

图片说明

我们知道每个 JavaScript 对象均有一个隐式的 proto 原型属性,而显式的原型属性是 prototype,只有 Object.prototype.proto 属性在未修改的情况下为 null 值

手动实现

function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
    var O = R.prototype;
    L = L.__proto__;
    while (true) { 
        if (L === null) 
        return false; 
        if (O === L) // 这里重点:当 O 严格等于 L 时,返回true 
        return true; 
        L = L.__proto__; 
    } 
}
// 开始测试
var a = []
var b = {}

function Foo(){}
var c = new Foo()
function child(){}
function father(){}
child.prototype = new father() 
var d = new child()

console.log(instance_of(a, Array)) // true
console.log(instance_of(b, Object)) // true
console.log(instance_of(b, Array)) // false
console.log(instance_of(a, Object)) // true
console.log(instance_of(c, Foo)) // true
console.log(instance_of(d, child)) // true
console.log(instance_of(d, father)) // true

2.18 数组去重

参考答案:

1. 利用ES6 Set去重(ES6中最常用)

function unique (arr) {
  return Array.from(new Set(arr))
}
var a

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

前端岗位面试真题宝典 文章被收录于专栏

本面试宝典均来自校招面试题目大数据进行的整理

全部评论

相关推荐

不愿透露姓名的神秘牛友
02-24 17:04
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务