运算符对于大家来说并不陌生,只要平时写代码就会频繁用的到。可能平时大家只关注它们的使用层还停留在只知其用法的表面,但是运算符有一些鲜为人知技能,明白以后会让你掌握运算符的原理和运算符的奇技淫巧以及解决一些面试题

先来看一些面试题,请小伙伴本着不去试的原则写出下而四道题的运行结果

//1
console.log('kaivon' && (2+1));
console.log(![] || '你好,siri');//2
{let a=10,b=20;const fn=()=>(a++,b++,10);console.log(a,b,fn());let c=fn(); console.log(a,b,c);
}//3
for(var i=0,j=0,k;i<6,j<10;i++,j++){k=i+j;
}
console.log(k);//4
{let a=1;let b=a++;console.log(a,b);let c=1;let d=++c;console.log(c,d);
}

对于面试题,我一开始是拒绝的,内心是崩溃的。总是会想这些题没有意义啊,真正在开发的时候谁会去做题呀,更不会遇到这么无聊的东西,为什么会用这种东西来面试?难道说面试官是过来装逼的么?看到我们回答不上来,一脸不屑地鄙视我们么?反过来想想,面试官跟我们无冤无仇,前端何苦为难前端?然而这些东西其实是有意义的,从你对这些题的回答可以看出你的基础知识全面性,并且能判断出你的技术能力。

以上面试题包含三种运算符,逻辑运算符、逗号运算符、递增递减运算符,我就分别来介绍这三种运算符

逻辑运算符

且运算符:&&

  • 并且的意思,至少需要两个数据(也可以为表达式)符号左右各一个。并且会把两边的结果转成布尔值
  • 如果左侧的值为真,返回右侧的值。如果左侧的值为假,返回左侧的值(不会计算右边的结果)
  • 只有当左右两边的结果都为真的时候,整个结果才为真(用于判断)
  • 且运算符可以出现多个,会依次按从左到右的顺序,遇到假的结果便返回。如果都为真则返回最后一个结果
console.log('kaivon' && (2+1)); //3

遇到&&运算符,先去计算左边的结果并转成布尔值,左边为字符串kaivon,它转为布尔值的结果为true,所以会返回&&运算符右侧的结果。右侧为一个表达式,计算后的结果为3,所以整个结果为3

console.log(![] && '你好,siri');  //false

左侧的表达式是把一个空数组转成布尔值(对象转基本数据类型的算法私信我要视频)并取反的结果。空数组转成布尔值结果为true,取反后结果为false。当左侧的结果为false时会直接返回,并不会去理会右侧的内容,所以直接返回左侧的结果false

let n=1;
n-1 && (n+=5);
console.log(n);     //1 左侧为假,所以不会执行右侧的结果,n不会加5const fn=()=>console.log('函数被调用了');
n==1 && fn();

第一个console.log的结果为1,说明n+=5这个表达式并没有执行。因为&&运算符左边的表达式运算结果为0转成布尔值为false,所以直接返回左边的结果,不会去管右边的表达式,所以n的值并不会变。
第二个console.log会打印出内容,说明&&运算符的右侧表达式被执行了,因为n的值并没有改变还是1,所以左边的表达式运行结果为true,根据规则会返回右侧的结果,所以执行调用函数fn

console.log(true && 'kaivon' && (2-2) && 4 && '陈学辉' && true);   //0 返回2-2的结果
console.log(true && 'kaivon' && [] && 4 && '陈学辉');   //陈学辉

根据上面最后一条规则可以很轻易得出上面的运算结果。运算会按从左到右的顺序执行,一旦遇到表达式的结果为false的话就会停止执行,并且整个表达式会返回这个运算结果。如果所有表达式的结果都为true,那整个结果为最后那个表达式的结果

或运算符:||

  • 或者的意思,至少需要两个数据(也可以为表达式)符号左右各一个。并且会把两边的结果转成布尔值
  • 如果左侧的值为真,返回左侧的值(不会计算右边的结果)。如果左侧的值为假,返回右侧的值
  • 如果有一边的结果为真的话,整个结果就为真(用于判断)
  • 或运算符可以出现多个,会依次按从左到右的顺序,遇到真的结果便返回。如果都为假则返回最后一个结果
let n=1;
n-1 || (n+=5);
console.log(n);     //6

||运算符左边表达运算结果为0转布尔值为false,根据上面列出的规则会返回右侧表达式执行的结果,所以会执行n+=5,最终n的结果为6

console.log(false || '' || (2-2) || 4 || '陈学辉' || true);    //4
console.log(false || '' || ![] || 0 || undefined);      //undefined

根据上面的规则也很容易知道运行结果,||运算符的左侧 运行结果为false的话就会执行右侧的表达式,直到遇到计算结果为true的表达式才会停下来,并返回这个值。如果所有表达式都没有返回true,则取最后表达式的结果

或运算符的用途:

function fn(text){text=text || 'kaivon';  //用户给了参数,取用户给的值;用户没有给参数,取默认值console.log(text);
}
fn();           //kaivon    用户没有传参数,就会用默认的'kaivon'
fn('陈学辉');  //陈学辉   用户有传参数,就会用传的参数

上面代码的这种形式是ES5写面向对象的主要形式,用于对参数进行处理。如果用户传了参数,那会取用户所传的参数;如果用户没有传参,那取默认的参数。保证函数始终有参数,不会报错

逗号运算符

  • 将多个表达式放在一条语句里,按从左到右的顺序执行每个表达式,返回最后那个表达式的结果(在一条语句里执行多个运算)
  • 优先级最低,最后才会运算逗号
  • 逗号运算符的两边不能是语句(赋值语句)
console.log(1,2,3);     //1 2 3
console.log((1,2,3));   //3     

console.log是个函数,它里面的逗号表示参数分隔的意思,并不是逗号操作符。要变成操作符的话,就加个括号,加个括号后就变成了表达式,而表达式必需要求出一个值,所以里面的逗号就变成了操作符

let a=10,b=(a++,20,30);
console.log(a,b);   //11 30

第一行代码中的第一个逗号的作用是:可以在一行中声明多个变量,减少let关键字。从第二个开始被放到了括号里,而加了括号后就是个表达式。还是那句话,表达式一定会产生一个值,这个时候逗号就是个运算符了,会把最后一个赋给变量,也就是30。

下面来详细分析一道面试题,再深度的理解一下逗号运算符

for(var i=0,j=0,k;i<6,j<10;i++,j++){k=i+j;
}
console.log(k); //18

很多小伙伴会说这个k的值不应该是14么?i的值走到5不就停了,j的值走到9不也停了,那加起来应该是14啊!为什么是18,这不科学啊!!!

要明白这个原因需要结合for循环的三条语句以及逗号运算符的作用去才能理解
说明:

  1. for循环的第一个语句var i=0,j=0,k是初始化一些变量,这里的逗号与上个代码块第一条语句的逗号一样,作用为在一行里声明多个变量
  2. for循环的第二个语句i&lt;6,j&lt;10作用为取一个循环范围,这里要注意循环范围只能有一个条件,不能说既小于5又小于8,所以这里的逗号就是真正的逗号运算符,它只能取一个值,取的就是最后那个j&lt;10
  3. for循环的第三个语句i++,j++,这条语句的逗号还是个运算符,表示在一行里执行多条语句,但是这个语句不需要有返回值,只用把语句执行了就行
  4. 综上所述,这个for循环表示:声明三个变量,条件范围为j&lt;10,同时i与j每走一次都要加一次。当j的值为9的时候就不再加了,此时i的值也一样会加到9它已经没有范围限制了会无限的加,但是j有范围并不会无限加。所以i的值是跟着j在走,得出结果i+j=18

逗号运算符的另一个作用:交换两个变量的值
声明两个变量,要求通过某种方式让两个变量的值进行交换,你会用什么方法?

let a=10;
let b=20;
//问:如何让a与b的值进行交换

有一种笨方法是利用一个中间变量可以完成,代码如下:

let a=10;
let b=20;
let c;c=a;
a=b;
b=c;console.log(a,b);   //20 10

利用逗号运算符,代码如下:

let a=10;
let b=20;a=[b][b=a,0];
console.log(a,b);   //20 10

可以看到利用逗号运算符倒是很容易实现需求,但是代码阅读起来好像很费劲,分析如下:

a=[b][b=a,0];   //这条代码的两个中括号表示,前面为数组,后面为下标。在数组中取某一个数据并赋值给aa=[20][b=10,0]  //分别把a与b的值套进去,注意第二个中括号里的b=a,这么写是把a的值赋给b,所以只能套a的值/** 重点看第二个中括号里的代码,此时这个中括号的作用为下标,所以里面必需产生一个值,那里面的逗号就是运算符了* 根据逗号运算符的作用,先执行两个表达式,把b的值改成10,再返回最后表达式的值0* 所以这个中括号牛比的地方有两个,第一个是把b的值改成了10,第二个是整体返回0。也就变成了下面
*/a=[20][0]   //这不表示把第0个数据的值(20)赋给a

所以,逗号运算符用巧了就是巧他妈给巧开门,巧到家了~

递增递减运算符

  • 它俩可以放在操作数的前面,也可以放在操作数的后面
  • 不管它俩放在哪个位置,都是一个表达式,表达式的话肯定返回一个值
  • 它俩具有隐式类型转数字的作用

首先验证表达有值,不管放前面还是放后面都会有值

let a=3;
console.log(a++);   //3
console.log(++a);   //5

后自增、后自减

  • 表达式结果为数据直接转数字后的值
  • 数据结果为加1或者减1的值
let a=['20'];
console.log(a++);   //20    表达式结果为a转数字后的值
console.log(a);     //21    数据本身变成了+1后的值let b='20';
console.log(b--);   //20    表达式结果为b转数字后的值
console.log(b);     //19    数据本身变成了-1后的值

前自增、前自减

  • 表达式与数据的结果一样,都为数据加1或者减1的值
let a=['20'];
console.log(++a);   //21    表达式结果为a转数字后并加1的值
console.log(a);     //21    数据本身也为a转数字后并加1的值let b='20';
console.log(--b);   //19    表达式结果为a转数字后并减1的值
console.log(b);     //19    数据本身也为a转数字后并减1的值

两种写法对比

  • 两种写法的区别在于表达式的结果不同。数据的结果写前面与写后面都一样
  • 如果要用表达式的结果,看谁在前面
    1. 数据在前面,结果为数据的值
    2. 符号在前面,结果为数据+1或者数据-1的值
{let a=1;let b=a++;console.log(a,b);   //2 1
}{let a=1;let b=++a;console.log(a,b);   //2 2
}

通过对比,a的值不管是在前面++还是在后面++,结果都为2(a+1的值)。但b的值(表达式的值)可以看谁在前面,a在前面那就取a的值,++在前面那就取a+1的值

善于总结!善于总结!善于总结!重要的提醒打三遍!

转载于:https://blog.51cto.com/13258913/2169942

你不知道的JavaScript运算符相关推荐

  1. 精读《你不知道的javascript》中卷

    前言 <你不知道的 javascript>是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途.本书< ...

  2. JavaScript运算符:递增递减运算符前置和后置的区别

    从两段代码说起 var num1 = 2; var num2 = 20; var num3 = --num1 + num2; var num4 = num1 + num2; console.log(n ...

  3. JavaScript强化教程——JavaScript 运算符

    本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程 -- JavaScript 运算符  JavaScript 算术运算符 算术运算符用于执行两个变量或值的运算 ...

  4. javascript运算符_JavaScript中的按位运算符

    javascript运算符 JavaScript按位运算符 (JavaScript Bitwise Operators) A lot of times you come across some str ...

  5. javascript运算符_JavaScript中!=或!==运算符之间的区别

    javascript运算符 We can perceive the differences between these two operators as the same difference tha ...

  6. 你不知道的javascript(上卷)----读书笔记

    <!DOCTYPE html> <html><head><meta charset="utf-8"><title>你不知 ...

  7. javascript 运算符优先级

    JavaScript 运算符优先级(从高到低) https://github.com/xhlwill/blog/issues/16 今天把js函数转换为python 函数时,发现在js运算符优先级这边 ...

  8. JS闭包—你不知道的JavaScript上卷读书笔记(二)

    关于闭包,初学者会被绕的晕头转向,在学习的路上也付出了很多精力来理解. 让我们一起来揭开闭包神秘的面纱. 闭包晦涩的定义 看过很多关于闭包的定义,很多讲的云里雾里,晦涩难懂.让不少人以为闭包是多么玄乎 ...

  9. JavaScript运算符的优先级(案例讲解)

    先来看看这道题... 下边代码输出的结果是( ) var val = 'smtg'; console.log('Value is ' + (val === 'smtg') ? 'Something' ...

最新文章

  1. docker卸载命令_使用docker完成生信分析环境搭建
  2. Java中的主类概念以及public static void main方法的分析
  3. 关于将struts2框架下,使自定义过滤器对部分的action(一个action或多个action)请求忽略的方法
  4. 嘉年华回顾丨 尚博带你了解腾讯 TXSQL如何 赋能腾讯云分布式数据库 CynosDB
  5. python requests库api_python利用requests库进行接口测试的方法详解
  6. centos mysql 主从_CentOS 搭建 MySql 主从备份
  7. C语言简明数据类型指南
  8. [原]ASP.NET中使用JQUERY-EASYUI后,解决ClientScript.RegisterStartupScript 所注册脚本执行两次...
  9. 日久见人心,以小见大
  10. c语言编译器 for mac,编译工具CMake for mac
  11. 我写的万年历插件(含天干地支,农历,阳历,节气,各种节假日等),基于MooTools 1.4
  12. SAP HANA2.0 EXPRESS 下载及安装详细教程---第一部分
  13. 优秀的管理者如何带好团队(这几个技巧你是否学会)
  14. 照片webp格式怎么改成jpg?
  15. post测试+php文件,PHPT – 无法运行使用–POST_RAW–的示例测试
  16. bp神经网络及ROC曲线绘制
  17. Java程序设计(二)
  18. ARIMA模型的拖尾截尾问题
  19. cordova NFC读卡(javascript)
  20. WPA-Enterprise WPA2-Enterprise以及WPA-Personal WPA2-Personal

热门文章

  1. java.lang.Enum
  2. QQ目录里哪个文件是记录系统消息的?
  3. CSS基础教程(企业内部培训)
  4. 操作系统原理第三章:进程
  5. 【OpenGL】十二、OpenGL 绘制线段 ( 绘制单条线段 | 绘制多条线段 | 依次连接的点组成的线 | 绘制圈 | 绘制彩色的线 )
  6. 【计算理论】计算理论总结 ( 下推自动机计算过程 | 上下文无关文法 CFG 转为下推自动机 PDA ) ★★
  7. Autodesk布道GIS新理念
  8. nginx高性能WEB服务器系列之九--nginx运维故障日常解决方案
  9. Android异常与性能优化相关面试问题-内存管理面试问题详解
  10. MyAdapter Andriod