/*===可有可无的开头start===*/
最近由于一些事儿辞了刚刚找到的工做,处在待业状态,去稍微的面了几家公司,有大有小,有好有坏,发现你们问起来的一些ES6的问题跟我想的不同,下来再去研究发现我说的仍是有些缺陷,虽然意思是对的,可是表达的很奇怪,怪不得面试官会误会,参考了下以前公司大哥的一些和网上大神的,这里捡着关于箭头函数和let、const去说一些浅陋的总结(都是烂大街的啦~)
/*===可有可无的开头end===*/前端
文中大部分偏建议,结合了网上的一些规范整理出来的,也包括了一些特殊的数组和对象的处理。后期你们一块儿讨论
ES6中两种方式进行函数的定义:箭头函数 和 function()面试
箭头函数的区别1: 没有本身的this,它的this来自它定义时的环境数组
箭头函数的区别2: 由于没有本身的this,因此bind、apply、call也对其不起做用闭包
箭头函数的区别3: 内部不能使用argumentsapp
因此总结起来就是,只要是须要用到内部的this和arguments的状况下,就不能使用箭头函数,这是一个基础,感受上只要注意这个,这两个能够随便用,下面总结了一下dom
let dom_test = documents.getElementById('test'); // 普通方式(正确) dom_test.addEventListener('click', function(){ // 用到了this指向当前的dom_test的dom对象 console.log('当前点击的按钮id是:' + this.id); // '当前点击的按钮id是:test' }) // 箭头函数方式(错误) dom_test.addEventListener('click',()=>{ // 当前的this指向了箭头函数定义位置的this,当前this指向window console.log('当前点击的按钮id是:' + this.id); // '当前点击的按钮id是:undefined' }) // 箭头函数方式(修正) dom_test.addEventListener('click',()=>{ // 避免这种this绑定到dom_test的使用场景,直接上变量 console.log('当前点击的按钮id是:' + dom_test.id); // '当前点击的按钮id是:test' })
// 普通形式(正确) function Student(name, age, className){ this.name = name; this.age = age; this.className = className; } new Student('Yupin Tu', 18, 'female'); // Student {name: "Yupin Tu", age: 18, className: "female"} // 错误的箭头函数 // 这样定义工厂方法时使用new执行会报 ‘XXX is not a constructor’ 的错误 let Student = (name, age, className)=>{ this.name = name; this.age = age; this.className = className; } new Student('Yupin Tu', 18, 'female'); // Uncaught TypeError: Student is not a constructor
// 普通方式(正确) let obj = { msg: 'this is a test', showMsg(){ // 用到了this指向obj console.log(this.msg); } } obj.showMsg(); // 'this is a test' // 箭头函数(错误) let obj = { msg: 'this is a test', showMsg:()=>{ //this指向了window console.log(this.msg); } } obj.showMsg(); // undefined
// 正确的 var getSum = function(){ const arr = [...arguments]; let sum = 0; for(let val of arr){ sum += val } return sum } getSum(1,2,3); //6 // 错误的 var getSum = ()=>{ const arr = [...arguments]; // 报错:arguments is not defined let sum = 0; for(let val of arr){ sum += val } return sum } // 修正 var getSum = (...rest)=>{ const arr = [...rest]; // 报错:arguments is not defined let sum = 0; for(let val of arr){ sum += val } return sum }
由于箭头函数没有this的状况,因此bind、apply、call对其不起做用,若是一个方法定义出来须要用在这个场景下,那么不能使用箭头函数(例如一个函数须要被进行柯里化的操做)函数
只要不涉及到this和arguments,箭头函数就可使用this
箭头函数的优点:rest
如下是适用场景code
let arr = [1,2,3] arr.map((val)=>val+1); //[2,3,4]
((msg)=>{console.log(msg)})('this is a test'); //'this is a test'
// 很差的使用 let obj = { msg: 'this is a test', getShowMsgFn(){ let _this = this; function showMsg(){ console.log(this.msg); //这时候this是指向window的,因此返回了undefined console.log(_this.msg); //这时候须要对外部的this引用到闭包内,然而_this没法释放,形成内存溢出 } return showMsg; } } obj.getShowMsgFn()(); // undefined 'this is a test' // 好的使用 let obj = { msg: 'this is a test', getShowMsgFn(){ let showMsg = ()=>{ console.log(this.msg); //这时候this是指向外部的this,也就是obj } return showMsg; } } obj.getShowMsgFn()(); // 'this is a test'
let和const指令针对于块级做用域,基本上能替换掉var的变量声明
let是用来声明会变化的变量的,而const是声明“常量或者是不可变化的变量”
/** * 由于const是块级做用域 * 因此若是一个变量在这个块里边声明以后再也不会进行赋值操做,应该使用cons * @TODO 但这里是否须要所有字母大写? */ const GMSG = ‘this is basic’; function(isChanged){ const staticMsg = 'this would be never changed'; let realtimeMsg = 'this is a test'; if(isChanged){ realtimeMsg = 'It's changed'; } return GMSG + staticMsg + realtimeMsg; }
let 和 const 声明的变量不会像 var 声明同样提高到做用域的最上边,因此如下状况请注意
首先看下没问题的var:
// 没问题的var方式,var声明的test会提高到最上边 function getStr(name){ if(name){ test = name; } var test; return test; } getStr('ZhangSan'); //'ZhangSan' window.test; // undefined // 以上代码同等于 function getStr(name){ var test; // 被提高到上边来啦 if(name){ test = name; } return test; }
看一下出问题的let,由于let不会提高,因此
function getStr(name){ if(name){ // 非严格模式下会在window上生成一个test属性去进行操做 // 严格模式直接报错:test is not defined test = name; } let test; return test; // 此时返回的是当前let出来的test,是个undefined } getStr('ZhangSan'); //undefined window.test; // 非严格模式下为'ZhangSan' ,严格模式下是undefined
var用在循环中
let arr = [1,2,3]; for(var i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // 3 //-----------------等同于----------------- let arr = [1,2,3]; var i; for(i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // 因此这里可以输出 3
而let的状况
let arr = [1,2,3]; for(let i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // undefined (?) // -------------由于它不等同于------------- let arr = [1,2,3]; let i; for(i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // 此时 i存在 为 3 // ---------------而是等同于-------------- let arr = [1,2,3]; let _i; // 一个for循环的内部迭代变量,不能访问 for(_i = 0 ; _i < arr.length ; _i++){ let i = _i; console.log(i); } // 1 2 3 console.log(i); // 此时 i存在 为 3
后边没了,下边的是一些人力面的总bao结yuan
/*===可有可无的结尾start===*/
面试是最快的查漏补缺的方式。
然而因为本身的工做经验主要在一家软件公司,而后后来的公司入职时间不长就又辞了,因此最近去互联网公司受到了人资的盘问,以为本身除了有点害羞表现还能够,因此也拿到了几家的offer,可是也是受尽了互联网公司人资的歧视(居然反问我以前软件公司还须要加班么)
最近去了某互联网媒体巨头某狐面试,经历了史无前例的人力面,在她满脸看不起个人在软件公司干了两年的工做经验中,我当心翼翼的回答着她挑衅的问题,自称互联网人的她对我以前的公司反复的羞辱和鄙视,我也是不卑不亢(毕竟我只是去试试感受),在最后问我为何大四上半年就签了工做,是否是不敢去互联网公司试试,仍是说大四下半年在忙着补考。而后我说把手机里的成绩单给她看(哈哈,大学仍是有点小成就的),她居然说我是有备而来,嗯,能够,大公司咄咄逼人呐
还有一些肉眼可见直插肺腑的地域歧视
这里也总结一下我被问到的问题
···
我家是河北沧州任丘,特别干净,由于考不上公务员才被迫来北京谋生,我以前的软件公司也很厉害,早就不是用JSP写前端页面了,加班是我热爱我作的工做,咱们大学是正正经经的重本大学,我上学那会儿保定的分不比北京低,我没有梦想,由于我不是汪峰,你们都是在这个城市靠手艺吃饭,到处充满优越感的人其实很自卑吧!
这篇文章过不了审核也无所谓了
/*===可有可无的结尾end===*/