面试

比特大陆

  1. 自己实现v-model
    v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
    v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
    text 和 textarea 元素使用 value 属性和 input 事件;
    checkbox 和 radio 使用 checked 属性和 change 事件;
    select 字段将 value 作为 prop 并将 change 作为事件。
  2. vue与react的区别
  3. 跨域解决方案(都问到了)-通信类
  4. 数组的哪些方法会改变原数组?
    push()、pop()、unshift()、shift()、splice()
    reverse():返回该数组,sort()返回该数组
    不改变原数组的方法:concat()、join()、slice()、toString()
  5. 说一下普通函数中的this与箭头函数中的this的区别?
    箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。
    箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。
    由于箭头函数没有自己的this指针,通过 call()或apply()方法调用一个函数时,他们的第一个参数会被忽略。
    没有参数的函数应该写成一对圆括号:() => {函数声明}
    当只有一个参数时,圆括号是可选的:单一参数 => {函数声明} 或 (单一参数) => {函数声明}
    多参:(参数1, 参数2, …, 参数N) => 表达式(单一) 或 (参数1, 参数2, …, 参数N) => { 函数声明 }
  6. vuex详解

云校电面

  1. 判断数据类型的方式:typeof、instanceof、constructor、toString().call()、jq中判断数据类型的方法
    在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示:
    基本类型:String、Number、Boolean、Symbol、Undefined、Null
    引用类型:Object,引用类型除 Object 外,还包括 Function 、Array、RegExp、Date 等等。
    typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示。
    对于基本类型,除 null 以外,均可以返回正确的结果;null返回 object 类型。
    对于引用类型,除 function 以外,一律返回 object 类型;function 返回function类型。
    null 有属于自己的数据类型 Null , 引用类型中的数组、日期、正则也都有属于自己的具体类型,而 typeof 对于这些类型的处理,只返回了处于其原型链最顶端的 Object 类型
    instanceof原理: 因为A instanceof B 可以判断A是不是B的实例,返回一个布尔值,由构造类型判断出数据类型
    toString.call([]); //[object Array]
    arr.constructor === Array //true 原型上的属性实例也能直接使用(继承而来)

    1
    2
    3
    4
    5
    6
    7
    8
    jQuery提供了一系列工具方法,用来判断数据类型,以弥补JavaScript原生的typeof运算符的不足。以下方法对参数进行判断,返回一个布尔值。
    jQuery.isArray();是否为数组
    jQuery.isEmptyObject();是否为空对象 (不含可枚举属性)。
    jQuery.isFunction():是否为函数
    jQuery.isNumberic():是否为数字
    jQuery.isPlainObject():是否为使用“{}”或“new Object”生成对象,而不是浏览器原生提供的对象。
    jQuery.isWindow(): 是否为window对象;
    jQuery.isXMLDoc(): 判断一个DOM节点是否处于XML文档中。
  2. 自己实现一个数组倒叙排列,考虑时间复杂度和空间复杂度
    (假设每个对象中有一个唯一的时间戳字段stamp)
    方法一:arr.reverse()
    方法二:数组倒叙遍历,时间复杂度:n
    方法三:arr.sort()
    方法四:冒泡排序法、二分排序法等
    sort() 方法用原地算法对数组的元素进行排序,并返回数组。排序算法现在是稳定的。默认排序顺序是根据字符串Unicode码点。
    由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。
    一句话总结就是: 原地算法不依赖额外的资源或者依赖少数的额外资源,仅依靠输出来覆盖输入的一种算法操作。
    没有指明 compareFunction,比较的数字会先被转换为字符串
    指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:小于0,正序;大于0,倒序,等于0,保持不变

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //demo
    let arr = [{stamp:1561196563527,name:'张三1'},{stamp:1561196591134,name:'张三2'},{stamp:1561196619297,name:'张三3'}];
    arr.sort((a,b)=>b.stamp-a.stamp)

    let sortArr = function(keyName){
    return function(obj1,obj2){
    return obj2[keyName]-obj1[keyName];//倒序
    //return obj1[keyName]-obj2[keyName];//正序
    }
    }
    console.log(arr.sort(sortArr('stamp')))
  3. http状态码

  4. vue的生命周期
    created 钩子可以用来在一个实例被创建之后执行代码:this` 指向 vm 实例,已经能获取到data中的数据
    mounted
    updated
    destroyed
    不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch(‘a’, newValue => this.myMethod())。因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

云校一面

  1. 选择器权重:标签选择器、属性选择器,并进行量化
  2. 实现全屏品字布局
  3. 实现一个深拷贝(递归实现)
    当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
    ie9+ 支持Array.isArray,属于es6语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    function deepClone(obj){
    //判断要拷贝的是数组还是对象:数组进行数组拷贝,对象进行对象拷贝
    //var objClone = obj.constructor == Array ? [] :{};
    //var objClone = obj instanceof Array ? [] : {};
    var objClone = Array.isArray(obj)? []:{};
    if(obj && typeof obj === 'object'){
    for(key in obj){
    if(obj.hasOwnProperty(key)){
    if(obj[key] && typeof obj[key] === 'object'){
    objClone[key] = deepClone(obj[key]);
    }else{
    objClone[key] = obj[key];
    }
    }
    }
    }
    return objClone;
    }
  4. 找出一个字符串中出现次数最多的字符,并统计次数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var str = 'asdfabcdaaa';
    var obj = {};
    for(var i=0;i<str.length;i++){
    if(obj[str.charAt(i)]){
    obj[str.charAt(i)]++;
    }else{
    obj[str.charAt(i)] = 1;
    }
    }
    var maxCount = 0;//变量接收最大值
    var maxIndex = -1;
    for(var key in obj){
    if(obj[key]>maxCount){
    maxCount = obj[key];
    maxIndex = i;
    }
    }
    console.log('出现次数做多的是:'+maxIndex+',出现次数:'+maxCount);
  5. 输出值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function person(name){
    if(name){
    this.name = name;
    }
    console.log(this);
    console.log(this.name);
    }
    person.prototype.name = 'parent';
    person();//Window,''
    person('child');//window,child
    new person();//person,parent
    new person('child2');//person,child2
    person.call(window);//window,child

解析:直接打印window对象,内部本身有name:’’,这是window自带属性,如果绑定的不是name,假设是test,
person();//Window,undefined

1
2
3
4
5
6
7
8
9
10
11
12
var a = window.a = "welcome to Here";
function hello(){
console.log(a);
function a(){

}
var a = 'soho';
console.log(a);
console.log(b);
let b = 'xxhashka';
}
hello();

结果:f a(){}、soho、reference error。
只声明不赋值之前,它是不会覆盖同名函数的,赋了值就变成一个具体值了,之后再去按方法调用的话会报错,提示不是一个方法
闭包解决for循环的问题:

1
2
3
4
5
6
7
for(var i=0;i<4;i++){
(function(i){
setTimeout(function(){
console.log(i);
},0)
})(i)
}

  1. 将字符串转成金额格式:num.toLocaleString();//12,345,678
  2. 返回100以内的所有素数(只有1和它本身两个因数的自然数)

    1
    2
    3
    4
    5
    6
    7
    8
    for(var i=1;i<=100;i++){
    for(var n=2;n<=i;n++){
    if(i%n==0&&i!=n){break;}
    else if(i==n){
    document.write(i+" ");
    }
    }
    }
  3. 数组排序:冒泡排序、快排、希尔排序
    冒泡排序:嵌套循环(如果前面的数字比后面大,交换位置(借助一个临时变量))
    快速排序:借助中间某个值,小于它的放到左边数组,大于它的放到右边数组,递归调用

  4. 异步执行方案(一道算法题,让说出console.log的打印顺序)
  5. 项目中的优化