快手一面给的感觉特别好 面试官人很nice 错的地方都会给讲解 可能跟他之前让我等了40分钟有关吧嘻嘻嘻
没让我自我介绍 自己自我介绍了了一波 调设备调了很久
1.css相关 给你一个定宽定高的弹层 如何实现水平垂直居中
第一种方法是使用position:absolute 设置margin-left和margin-top 或者left top
第二 display:table display:table-cell(并不能)
自动换行:word-break:break-all(有根据各种语言规则来决定断开的字符)
不换行:white-space:nowarp
共有四种:
第一:.father{
    position: relative;
height:300px;
300px;
}
.son{
    position: absolute;
height:300px;
300px;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;  
}//若不设置父类高度 在body直接写son  显示根据屏幕的宽高居中
第二:.father{
    position: relative;
height:300px;
300px;
}
.son{
    position: absolute;
    left: 50%;
    top: 50%;
 50px;
			height: 50px;
    margin-left: -50px;//(.kuangao元素宽度的一半)
    margin-top: -25px;//(.kuangao元素高度的一半)  
}////若不设置父类高度 在body直接写son  显示根据屏幕的宽高居中
第三:
.father{
    position: relative;
}
.son{
    position: absolute;
    left: 50%; 
    top: 50%;  
    transform: translate(-50%,-50%); 
 }
只设置son的宽高为百分数的形式 会居中于整个屏幕
第四:
.son{
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;  
    z-index: 999;
}//此方法为居中于屏幕  按F12后拖拉 也是在屏幕中间的  只需设置子元素长宽 此时的父元素为整个屏幕
不定宽不定高:
vertical-align是设置垂直对齐方式;该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐
值middle:放置于父元素的中部 texe-top:元素的顶端与与父元素的顶端对齐
使用 translate 的例子的 offsetTop 和 offsetLeft 的数值与没有产生位移的元素没有然后区别,无论位移多少这两个数值都是固定不变的。
而使用相对定位的例子 offsetTop 和 offsetLeft 的数值则根据位移的长度发生了改变。
2.js相关 数据类型有哪几种
alert()各种typeof的输出结果
var a = {};alert(typeof a);//object
var a = null;alert(typeof a);//object
function aa(){alert(“fsdfs”)};
alert(typeof aa);//function
var bb = new aa();
alert(typeof bb);//fsdfs
数据类型的’==’
alert(null == undefined); //输出 "true"
alert(NaN == NaN); //输出 "false"
alert(isNaN("blue"));  //输出 "true"
alert(isNaN("666"));  //输出 "false"
变量 oTemp2 从未被声明过。如果对 oTemp2 使用除 typeof 之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。
if(a==undefined){alert(“jjj”)}; //jjj
通过内置对象和内置函数(构造函数)new出来的对象 typeof后的得到的都是object 除了function返回function
换句话内置函数构造出来的变量都是封装了基本数据类型的对象除了function()返回function
a)var a=new String(“abb”);
console.log(typeof(a));//object
console.log(typeof “dhj”);//string
b)var a=new Number(111);
console.log(typeof(a));//object
console.log(typeof 11);//number
为了知道对象(构造出来的对象)的真正的类型可以使用下面的方法
Object.prototype.toString.call([1,2,3]);//”[object,array]”,后面的一个值即为传入参数的类型
自定义构造函数的类型
a)function Person(name){
	this.name = name;
}
var person = new Person(“song”);
console.log(typeof person);//object
b)function Person(name){ this.name = name; }
console.log(typeof Person);//function
//构造函数
负浮点数或加’+’号的正浮点数直接跟上.toString(),相当于先运行toString()方法,再添加正负号,转换为数字
3.关于预解析和函数执行
/* 匿名函数fn明明没调用啊,怎么也会输出呢,下面我把代码简化一下,你们就能看懂了! */
var fn = function(){ console.log(123); }(function(){console.log(789);}()) /* 可以很明显的看到(function(){console.log(789);}())这个自执行函数调用输出了789,
同时,这个自执行函数跟在匿名函数的后面,Js解析的时候把这个匿名函数也解析成为了自执行函数,
所以就输出了123. 解决的办法很简单,在第一个匿名函数的后面加一个;或者直接采取第一种写法就能避免这种问题 */
预解析过程: 
1.把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。 
2.把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。 
3.先提升var,在提升function
只要是通过var定义的,不管是变量,还是函数,都是先赋值undefined,如果是变量,也不管变量有没有赋值,在预解析阶段,都是会被赋值为undefined。
function进行预解析的时候,不仅是声明而且还定义(define)了,但是它存储的数据的那个空间里面存储的是代码是字符串,没有任何意义。
alert(a); //弹出的是下面的function
function a(){
  alert(“预解析function”)
}
两次都是输出:function a(){var c;}
题目一:
题目二:
题目三:
var n = 0;
function a(){
var n = 10;
function b(){
n++;
alert(n);
}
b();
return b;
}
var c = a(); //a()执行一次,弹出11,并且把返回值赋给c,此时的c为function b(){}
c(); //alert(n),12
alert(n); // 0
题目四:
var n = 99;
function outer(){
var n = 0;
return function inner(){
return n++;
}
}
var c = outer(); //c=function inner(){ return n++; }
var num1 = c(); //0,然后再执行n++ 此时n=1;
var num2 = c(); //1, n++ 2;
var d = outer(); //重新开辟新
var num3 = d(); //0
当我们的一个函数返回一个新的function,我们在外面定义一个变量来接收,这样这个函数的内存就不能在执行完成后自动销毁,也就是我们所谓的函数内存被占用了。
4.闭包的理解 手写闭包
闭包一共有几种形式:
第一种:函数作为返回值被返回
var F = function(){
    var b = 'local';
    var N = function(){
        return b;
    }
    return N;
}
console.log(F()());
我的写法:
var F = function(){
    var b = 'local';
    return function(){
        return b;
    }
}
console.log(F()());
然而面试关说不是闭包
第二种:函数赋值(赋值给外部的一个变量)
var inner;
var F = function(){
    var b = 'local';
    var N = function(){
        return b;
    };
    inner = N;
};
F();
console.log(inner());
第三种:函数参数
var Inner = function(fn){
    console.log(fn());
}
var F = function(){
    var b = 'local';
    var N = function(){
        return b;
    }
    Inner(N);
}
F();
第四种:iife
function Inner(fn){
    console.log(fn());
}
(function(){
    var b = 'local';
    var N = function(){
        return b;
    }
    Inner(N);
})();
第五种:循环赋值
function foo(){
    var arr = [];
    for(var i = 0; i < 2; i++){
        arr[i] = function(){
            return i;
        }
    }
    return arr;
}
var bar = foo();
console.log(bar[0]());//2  
正确写法
function foo(){
    var arr = [];
    for(var i = 0; i < 2; i++){
        arr[i] = (function fn(j){
            return function test(){
                return j;
            }
        })(i);
    }
    return arr;
}
var bar = foo();
console.log(bar[0]());//0 
第六种:getter,setter
var getValue,setValue;
(function(){
    var secret = 0;
    getValue = function(){
        return secret;
    }
    setValue = function(v){
        if(typeof v === 'number'){
            secret = v;
        }
    }
})();
console.log(getValue());//0
setValue(1);
console.log(getValue());//1
第七种:
var add = (function(){
    var counter = 0;
    return function(){
        return ++counter; 
    }
})();
console.log(add())//1 console.log(add())//2
第八种:区分首次
var firstLoad = (function(){
  var _list = [];
  return function(id){
    if(_list.indexOf(id) >= 0){
      return false;
    }else{
      _list.push(id);
      return true;
    }
  }
})();
firstLoad(10);//true
firstLoad(10);//false
firstLoad(20);//true
firstLoad(20);//false
第九种:缓存机制(通过闭包加入缓存机制,使得相同的参数不用重复计算,来提高函数的性能)
var mult = function(){
  var a = 1;
  for(var i = 0,len = arguments.length; i<len; i++){
    a = a * arguments[i];
  }
  return a;
}
加入缓存机制后
var mult = function(){
  var cache = {};
  var calculate = function(){
    var a = 1;
    for(var i = 0,len = arguments.length; i<len; i++){
      a = a * arguments[i];
    }
    return a;
  };
  return function(){
    var args = Array.prototype.join.call(arguments,',');
    if(args in cache){
      return cache[args];
    }
    return cache[args] = calculate.apply(null,arguments);
  }
}()
第十种:img对象
var report = (function(){
  var imgs = [];
  return function(src){
    var img = new Image();
    imgs.push(img);
    img.src = src;
  }
})()
report('http://xx.com/getUserInfo');
5.写一个最拿手的继承 缺点是什么
构造函数的call继承 原型方法原型链继承
缺点是:没缺点
6.平均效率最高的排序算法 时间复杂度和空间复杂度的理解
快速排序 nlogn
7.25个人 5个跑道 选出前三名
七次
反正应该是凉了
扩展:
判断某个数是不是浮点数
js的原生方法 像isNaN(),isFinite(),在前者Infinity是不属于NaN的,会返回false,所以有些时候并不好用。而后者则是判断是否为有效数字,包括无穷值和非数字的都会返回false。
方法一:正则表达式
方法二:
若~5,则会返回 -num-1,所以~5就是-6
所以如果一个数是整数就可以通过两次取非可以相等 若是浮点数就不能了
方法三:正常来说,int % 1 === 0,但若是float % 1,却不再是0了,对吧!所以根据特性我们可以用下面的这种方法。
方法四:n != parseInt(n);
















