箭头函数和let、const声明小总结

/*===无关紧要的开头start===*/
最近因为一些事儿辞了刚刚找到的工作,处在待业状态,去稍微的面了几家公司,有大有小,有好有坏,发现大家问起来的一些ES6的问题跟我想的不一样,下来再去研究发现我说的还是有些缺陷,虽然意思是对的,但是表达的很奇怪,怪不得面试官会误会,参考了下之前公司大哥的一些和网上大神的,这里捡着关于箭头函数和let、const去说一些浅陋的总结(都是烂大街的啦~)
/*===无关紧要的开头end===*/

文中大部分偏建议,结合了网上的一些规范整理出来的,也包括了一些特殊的数组和对象的处理。后期大家一起讨论

一、函数声明的不同使用方式

ES6中两种方式进行函数的定义:箭头函数 和 function()

箭头函数的区别1: 没有自己的this,它的this来自它定义时的环境

箭头函数的区别2: 因为没有自己的this,所以bind、apply、call也对其不起作用

箭头函数的区别3: 内部不能使用arguments

所以总结起来就是,只要是需要用到内部的this和arguments的情况下,就不能使用箭头函数,这是一个基础,感觉上只要注意这个,这两个可以随便用,下面总结了一下

1. 不适合用箭头函数的场景

1) 绑定事件的回调中使用this去代表当前绑定的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'
})
2) 定义构造器(工厂方法)时箭头函数不能使用
// 普通形式(正确)
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
3) 定义对象的方法属性时用到了this指向当前对象的时候
// 普通方式(正确)
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
4) 使用arguments的场景
// 正确的
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
}
5)要应用到bind、apply、call的时候

因为箭头函数没有this的情况,所以bind、apply、call对其不起作用,如果一个方法定义出来需要用在这个场景下,那么不能使用箭头函数(例如一个函数需要被进行柯里化的操作)

2. 适合用箭头函数的场景

只要不涉及到this和arguments,箭头函数就可以使用

箭头函数的优势:

  1. 简单快捷
  2. 可以利用其this的继承性减少外层this的传递

以下是适用场景

1) 在 map、reduce、filter 的回调函数定义
let arr = [1,2,3]
arr.map((val)=>val+1); //[2,3,4]
2) 立即执行
((msg)=>{console.log(msg)})('this is a test'); //'this is a test'
3) 需要传递外部this的情况(闭包或者作用域内定义的函数)
// 不好的使用
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指令针对于块级作用域,基本上能替换掉var的变量声明

1.let和const的使用上的区分:

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;
}

2. 替换var的时候由需要注意:

1)let 和 const 不会进行作用域内的提升

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
2)let在for循环中的定义

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,但是也是受尽了互联网公司人资的歧视(竟然反问我之前软件公司还需要加班么)

最近去了某互联网媒体巨头某狐面试,经历了前所未有的人力面,在她满脸看不起我的在软件公司干了两年的工作经验中,我小心翼翼的回答着她挑衅的问题,自称互联网人的她对我之前的公司反复的羞辱和鄙视,我也是不卑不亢(毕竟我只是去试试感觉),在最后问我为什么大四上半年就签了工作,是不是不敢去互联网公司试试,还是说大四下半年在忙着补考。然后我说把手机里的成绩单给她看(哈哈,大学还是有点小成就的),她竟然说我是有备而来,嗯,可以,大公司咄咄逼人呐

还有一些肉眼可见直插肺腑的地域歧视

这里也总结一下我被问到的问题

  1. 任丘是哪的啊,你下次直接写到沧州就好了
  2. 哦,我去过沧州,感觉挺乱的
  3. 你从县城来,怎么没有回家考公务员
  4. 你们软件公司还加班?你们加班干什么啊?
  5. 你们大学是华北电力大学在保定的分校么,是那个三本么
  6. 你的梦想是什么,我们公司都是有梦想的人,你没梦想可不行

···

我家是河北沧州任丘,特别干净,因为考不上公务员才被迫来北京谋生,我之前的软件公司也很厉害,早就不是用JSP写前端页面了,加班是我热爱我做的工作,我们大学是正正经经的重本大学,我上学那会儿保定的分不比北京低,我没有梦想,因为我不是汪峰,大家都是在这个城市靠手艺吃饭,处处充满优越感的人其实很自卑吧!

这篇文章过不了审核也无所谓了

/*===无关紧要的结尾end===*/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为AI语言模型,我不会使用 JavaScript,但我可以尝试回答你的问题。 JavaScript是一种非常强大的编程语言,它可以用于编写各种类型的应用程序,包括Web应用程序、桌面应用程序和移动应用程序等。在JavaScript编程中,数组、函数和类是非常常用的语言结构。下面是它们在实践中的一些用法。 1. 数组(Array):数组是一种存储数据的容器,可以存储不同类型的数据例如字符串、数字和布尔值等。JavaScript中的数组可以通过数组字面量或new Array()构造函数来创建,例如: ``` let arr = ['apple', 'banana', 'orange']; let numArr = new Array(1, 2, 3, 4, 5); ``` 通过[]的方式创建数组比使用new Array()更为常见。 对于数组中的数据,可以通过索引访问和修改,例如: ``` console.log(arr[0]); // 输出 'apple' arr[1] = 'pear'; console.log(arr); // ['apple', 'pear', 'orange'] ``` 还可以通过循环遍历数组中的数据,例如: ``` for (let i = 0; i < arr.length; i++) { console.log(arr[i]); } ``` 2. 函数(Function):函数是一组可以重复使用的代码片段,可以接收输入参数和返回输出值。JavaScript中的函数可以通过函数声明或函数表达式来创建。例如: 函数声明: ``` function add(num1, num2) { return num1 + num2; } ``` 函数表达式: ``` const add = function(num1, num2) { return num1 + num2; }; ``` 箭头函数: ``` const add = (num1, num2) => num1 + num2; ``` 函数可以通过调用来执行,例如: ``` console.log(add(1, 2)); // 输出 3 ``` 函数还可以作为参数传递给其他函数,例如: ``` function multiply(num1, num2) { return num1 * num2; } console.log(multiply(5, add(1, 2))); // 输出 15 ``` 3. 类(Class):类是一种提供了一组属性和方法的模板,可以用来创建对象。JavaScript中的类可以通过class关键字来创建,例如: ``` class Person { constructor(name, age) { this.name = name; this.age = age; } sayHi() { console.log(`Hi, my name is ${this.name}, and I'm ${this.age} years old.`); } } ``` 类的实例可以通过new关键字来创建,例如: ``` const person1 = new Person('Tom', 25); console.log(person1.name); // 输出 'Tom' person1.sayHi(); // 输出 'Hi, my name is Tom, and I'm 25 years old.' ``` 类还可以继承其他类,例如: ``` class Student extends Person { constructor(name, age, grade) { super(name, age); this.grade = grade; } study() { console.log(`I'm studying in grade ${this.grade}.`); } } ``` 现在,我们可以创建Student的实例: ``` const student1 = new Student('Peter', 18, 12); console.log(student1.name); // 输出 'Peter' student1.sayHi(); // 输出 'Hi, my name is Peter, and I'm 18 years old.' student1.study(); // 输出 'I'm studying in grade 12.' ``` 总结:JavaScript中的数组、函数和类是非常常用的语言结构,可以在不同的应用场景中使用。对于每个结构,我们都提供了相应的创建和使用示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值