久经沙场的前辈写过无数代码,踩过无数坑。但是有一些坑可能一辈子都碰不到,因为在业务代码中永远不会发生~~1.Function.prototype其实就是一个函数类型。自定义函数的原型是一个对象类型。typeofFunction.prototype==='function';//truefunctionPeople(){}typeofPeople.prototype==='object';//true所以我们可以设置一个空函数来做这个://Goodconstnoop=Function.prototype;//Badconstnoop=()=>{};2.一个变量真的不能等于它自己吗?constx=NaN;x!==x//true这是目前js语言中唯一不等于自身的数据。为什么?因为NaN代表的是一个范围,而不是一个具体的值。在早期的isNaN()函数中,即使传入一个字符串,它也会返回true,这个问题在es6中已经得到修复。isNaN('abc');//trueNumber.isNaN('abc')//false所以如果你想兼容旧的浏览器,使用x!==x来判断是否为NaN是一个很好的解决方案。3.如果构造函数返回新数据//不返回functionPeople(){}constpeople=newPeople();//People{}//返回数字}//返回一个新对象functionAnimal(){return{hello:'world',};}constanimal=newAnimal();//{hello:'world'}实例化构造函数时,返回非对象类型不会4.call.call给谁打电话?functionfn1(){console.log(1);}functionfn2(){console.log(2);}fn1.call.call(fn2);//2所以fn1.call.call(fn2)等价于fn2。调用(未定义)。而且无论添加多少个.calls,效果都是一样的。5、实例化后的对象是否可以再次实例化?functionPeople(){}constlili=newPeople();//People{}constlucy=newtom.constructor();//People{}因为lili的原型链指向People的原型,所以通过查找特征,它终于在Peopleel找到了。构造函数是在原型上找到的,也就是People本身6.setTimeout嵌套时会发生什么奇怪的事情?console.log(0,Date.now());setTimeout(()=>{console.log(1,Date.now());setTimeout(()=>{console.log(2,Date.now());setTimeout(()=>{console.log(3,Date.now());setTimeout(()=>{console.log(4,Date.now());setTimeout(()=>{console.log(5,Date.now());setTimeout(()=>{console.log(6,Date.now());});});});});});在0-4层,setTimeout的间隔是1ms,到了5层,间隔至少是4ms。7、es6函数有默认参数时,会生成声明作用域varx=10;functionfn(x=2,y=function(){returnx+1}){varx=5;returny();}fn();//38.函数表达式(非函数声明)中的函数名不能被覆盖constc=functionCC(){CC=123;returnCC;};c();//Function当然,如果你设置了varCC=123,添加声明关键字可以覆盖。9、严格模式下函数的this是undefined代替Window//non-strictfunctionfn1(){returnthis;}fn1();//Window//strictfunctionfn2(){'usestrict';returnthis;}fn2();//undefined对于webpack打包的模块化代码,基本都是严格模式下的代码。10.舍入运算也可以使用按位运算varx=1.23|0;//1因为按位运算只支持32位整数,所以小数点全部舍弃11.indexOf()不需要比较数constarr=[1,2,3];//存在,相当于>-1if(~arr.indexOf(1)){}//不存在,相当于===-1!~arr.indexOf(1);按位运算效率更高,代码更简单。您还可以使用es6的includes()。但是,如果在写开源库的时候需要考虑兼容性,还是用indexOf比较好。12.getter/setter可以动态设置吗?classHello{_name='lucy';getName(){returnthis._name;}//staticgettergetid(){return1;}}consthel=newHello();hel.name;//undefinedhel.getName();//lucy//DynamicgetterHello.prototype.__defineGetter__('name',function(){returnthis._name;});Hello.prototype.__defineSetter__('name',function(value){this._name=value;});hel.name;//lucyhel.getName();//lucyhel.name='jimi';hel.name;//jimihel.getName();//jimi130.3-0.2!==0.1//真正的浮点运算Imprecise,老生常谈,但可以接受的错误0.3-0.2-0.1<=Number.EPSILON//true14.class语法糖是如何继承的?functionSuper(){this.a=1;}functionChild(){//属性继承Super.call(this);this.b=2;}//原型继承Child.prototype=newSuper();constchild=newChild();child.a;//1正式代码的原型继承,不是直接实例化父类,而是实例化一个空函数,避免重复声明动态属性contextends=(Child,Super)=>{constfn=function(){};fn.prototype=Super.prototype;Child.prototype=newfn();ChildChild.prototype.constructor=Child;};15es6其实可以反复解构对象constobj={a:{b:1},c:2};const{a:{b},a}=obj;一行代码同时获取a和a.b。当a和b都被多次使用时,普通人的逻辑是先解构a,再在下一行解构b。16判断代码是否被压缩其实这么好17Object===比较内存地址,>=会比较转换后的值{}==={}//false//隐式转换为String(){}>={}//true18intanceof判断是否为原型在当前对象的原型链上People.prototype={};maninstanceofPeople;//false如果使用es6类,prototype原型是不允许重新定义的,所以不会出现上面的情况19Object.prototype.__proto__===null;//true这个是原型链向上搜索的最顶层,一个null20parseInt太小的数字会产生bugparseInt(0.00000000454);//4parseInt(10.23);//10211+null//11+undefined//NaNNumber(null)//0Number(undefined)//NaN22arguments和形参是别名关系functiontest(a,b){console.log(a,b);//2,3arguments[0]=100;arguments[1]=200;console.log(a,b);//100,200}测试(2,3);但是你可以使用严格模式来避免这种行为,所以参数只是一个副本。23void是个倔老头dowithanyone亲戚~~24try/catch/finally也有特定的执行顺序(){try{thrownewError('');}catch(e){returnfn1();}finally{returnfn2();}}console.log(getData());//打印顺序:'fn1','fn2',2intry/catch代码块中,如果返回xxyyzz;遇到关键字,则先执行xxyyzz并将值放入临时变量,然后执行finally代码块的内容,返回临时变量。如果finally中也有returnaabbcc,那么新的数据aabbcc会立即返回。25是否存在这样一个变量x使得它等于多个数?constx={value:0,toString(){return++this.value;}}x==1&&x==2&&x==3;//通过隐式转换为true,所以不难。26clearTimeout和clearInterval可以互换使用~~~~vartimeout=setTimeout(()=>console.log(1),1000);varinterval=setInterval(()=>console.log(2),800);clearInterval(timeout);清除超时(间隔);答案是:是的。大多数浏览器都支持相互清理定时器,但建议使用相应的清理函数。27下面的打印顺序是什么?setTimeout(()=>{console.log(1);},0);newPromise((resolve)=>{console.log(2);resolve();}).then(()=>console.log(3));functioncallMe(){console.log(4);}(async()=>{awaitcallMe();console.log(5);})();答案是:2,4,3,5,1主任务:2,4微任务:3,5宏任务:128Null是object类型,但它不是继承自Object,更像是历史遗留下来的bug。鉴于有这么多人在使用这个功能,修复它会导致成千上万的程序失败。typeofnull==='object';//trueObject.prototype.toString.call(null);//[objectNull]nullinstanceofObject;//falsehead为空,想着加。..
