第11节 Javascript运算符-零点程序员-王唯
wxin55 2024-11-21 22:16 7 浏览 0 评论
关系(比较)运算符:
关系运算符用于测试两个值的关系,根据它们的关系而返回true或false;通常应用在if、while等控制语句中,用于控制程序的执行流程。
> < <= >=这几个关系操作符用于对两个值进行比较,返回一个布尔值;
其会遵循以下规则:
- 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值;
- 如果一个操作数是数值,则将另一个操作数转换为一个数值,再执行数值比较;
- 如果一个操作数是对象,则调用对象的valueOf()或toString()方法,得到的结果再进行比较;
- 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较;
- Infinity比任何数字都大(除了其本身),-Infinity比任何数字都小(除了其本身);
- 任何操作数与NaN进行关系比较,结果都是false;
- 被认定为false的值:undefined、null、NaN、””、0、false;
在比较字符串值时,小于的意思是“在字母表中的位置靠前”,而大于的意味着“在字母表中的位置靠后”,但实际上不是这样。在比较字符串时,实际比较的是两个字符串中对应位置的每个字符的字符编码(ASCII)值;
console.log("brick" < "alpha"); // false
注:B的字符编码是66,而小写字母a的字符编码是97;
console.log("Brick".toLowerCase() < "alpha".toLowerCase()); // false
说明:通过把两个操作数全部转换成小写,就能得到正确的判断了;
另外一个现象是发生在比较两个数字字符串上,
如:var result = "23" < "3"; // 返回true
说明:这是合理的,因为先比较字符2和3(2的字符编码是50,3是51);
如:var result = "23" < 3; // 返回fase
说明,因为字符串23被转换为数字23;
注:如果其中一个操作数是字母:如:var result = "a" < 3; // 返回false;
说明:由于字母a不能转换成合理的数值,因此就被转换成了NaN;根据规则,任何操作数与NaN进行关系比较,结果都是false,因此,会出现一个特殊的情况:
如:var result = NaN < 3; // 返回false var result = NaN >= 3; // 同样返回false
由此:var result = NaN == NaN; // 返回false
相等操作符:
确定两个操作数是否相等是编程中一个非常重要的操作;在比较字符串、数值和布尔值的相等时,是比较简单的;但是在涉及到对象的比较时,相对比较复杂;在最早的ECMAScript中执行相等操作前,先将对象转换成相似的类型,再执行相等操作;后来,又出现了不转换直接比较的方案;这两种方案就导致出现了两组相等操作符:相等和不相等(先转换再比较)、全等和不全等(仅比较不转换);
相等与不相等(== !=):
由两个等于号==表示;如果相等,返回true;不相等由叹号和等于号!=表示,如果不相等,返回true;
这两个操作符都会先转换操作数(通常称为强制转换),然后再比较它们的相等性;
注:与=的区别,=是赋值运算符;
相等与不相等遵循下列规则:
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值:false为0,true为1;
- 如果一个操作数是字符串,另一个操作数是数值,先将字符串转换为数值:”1” == true
- 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf(),再按前面的规则比较;
- null和undefined是相等的;
- 在比较相等性之前,不能将null和undefined转换成其他任何值;
- 如果有一个操作数是NaN,则相等操作符返回false,不相等操作符返回true; 注:即使两个操作数都是NaN,相等也会返回false,不相等返回true,因为NaN不等于NaN;
- 如果两个数都是对象,使用的是引用的比较,不是值的比较,即两个对象不会相等,即使拥有同样的属性和属性值;但如果两个操作数都指向同一个对象,则相等;
全等和不全等(=== !==):
或称为严格相等,也时也称为恒等运算符;除了在比较之前不转换操作数之外,全等和不全等操作符与相等和不相等操作符没有什么区别;全等操作符只在两个操作数未经转换就相等的情况下返回true;
如:var result = "55" == 55; // true var result = "55" === 55; // false
0与-0全等;
两个操作数都指向同一个对象,则全等;
不全等操作符在两个操作数未经转换就不相等的情况下返回true
如:var result = "55" != 55; // false var result = "55" !== 55; // true
NaN与任意值都不相等,包括它本身;通过x!==x来判断x是否为NaN,只有在x为NaN时,这个表达式才返回true;
两个字符串显示出来的字符一样,但使用了不同的编码,不全等,String.localeCompare()专门用于比较字符串的方法。
null === undefined会返回false,因为它们是不同类型的值;
注:因为相等和不相等操作符存在类型转换问题,而为了保持代码中数据类型的完整性,推荐使用全等和不全等操作符;
条件运算符(?:):
条件运算符是ECMAScript最灵活的一种操作符了,它是ES中唯一的三元运算符;
语法:variable = exp1? value1 : value2;
基于对exp1求值的结果,决定给变量variable该赋什么值;如果求值结果为true,则返回value1值,如果求值结果为false,则返回value2值;value1与value2只会计算其中之一,不可能两者同时执行:
var num1=10, num2 = 20;
var max = num1 > num2 ? num1 : num2; // 求最大值
console.log(max);
var x = -5;
console.log(x > 0 ? x : -x); // 求绝对值
说明:使用if语句也会达到同样的效果,“?:”运算符只是提供了一种简写形式,如:判断一个变量是否有定义,如果有定义则使用它,否则使用一个默认值:
var username;
username = "wangwei";
var greeting = "hello," + (username ? username : "there");
console.log(greeting);
// 等价:
var username;
username = "wangwei";
var greeting = "hello,";
if(username){
greeting += username;
}else{
greeting += "there";
}
console.log(greeting);
逻辑(布尔)运算符:
在一门编程语言中,逻辑运算符非常重要;如果没有测试两个值关系的能力,那么诸如if和循环之类的语句就不会存在了;逻辑运算符一共有3个,非(!NOT)、与(&& AND)、或(|| OR);
逻辑非(!):
逻辑非运算符是一元运算符 ,可以应用于ECMAScript任何值;无论这个值是什么类型,这个操作符都会返回一个布尔值;逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反;如:
var x = false;
console.log(!x);
其遵循以下规则:
如果操作数是0、false、null、undefined、NaN、空字符串等返回true,否则返回false;
console.log(!false); // true
console.log(!"blue"); // false
console.log(!0); // true
console.log(!NaN); // true
console.log(!""); // true
console.log(!1234); // false
逻辑非操作也可以用于将一个值转换为与其对应的布尔值;而同时使用两个逻辑非操作符,实际上就会模拟Boolean()转型函数的行为;其中,第一个逻辑非操作会基于无论什么操作数返回一个布尔值,而第二个逻辑非操作则对该布尔值取反,于是就得到了这个值真正的对应的布尔值;当然,最终结果与对这个值使用Boolean函数相同;如:
console.log(!!false); // false
console.log(!!"blue"); // true
console.log(!!0); // false
console.log(!!NaN); // false
console.log(!!""); // false
console.log(!!1234); // true
逻辑与(&&):
逻辑与操作符由两个和号 && 表示,有两个操作数,如:var result = true && false;
var x = y = 0;
console.log(x == 0 && y == 0);
逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值;在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值;此时,它遵循以下规则:
如果第一个操作数是null、undefined、false、0、-0、NaN或空字符串,则返回其对应值;
如果第一个操作数是真值,则返回第二个操作数;
var a = 0 && 2 + 2; // 0
var a = 1 && 2; // 2
var a = 1 && 2 && 3; // 3
var a = 1 && 0 && 3; // 0
var a = 1 + 1 && 1 - 1; // 0
console.log(a); // 即遇到假就返回
// 再如:
var o = {};
var arr = [];
console.log(o && arr);
深入了解:即第一个操作数是假值的话,整个表达式的结果也一定是假值,因此&&此时就立即返回第一个操作数的值,而不会对第二个操作数进行计算。
如果第一个操作数是真值的话,那么整个表达式的结果由依赖于第二个操作数,如果其为真值,则整个表达式的值一定是真值,否则是假值,因此,当第一个操作数为真值时,&&将计算第二个操作数的值并将其返回;
var o = {x : 1};
var p = null;
console.log(o && o.x);
// console.log(p.x); // 抛出错误,因为并不存在
console.log(p && p.x); // null p是假值,因此将其返回,并不会去计算p.x
逻辑与的这种行为称为短路操作,如:
2>1 && document.write("ok"); // 与if语句有点类似
在真实场景中会使用这种特性来有条件的执行代码,如有时我们从后端拿过数据,但不知道这个数据有没有。如:
var data;
data = {};
data && document.write("有数据了");
// 或者
var found = true;
if(found){
somFun();
}
// 等同于:
var found = true;
found && somFun();
// 再如:
var year = 2022;
var str;
year > 2020 && (str = year + "年发大财!"); // str的值依赖于左侧操作数
console.log(str);
虽然在大多数情况下,&&仅用来对表达式进行简单的布尔计算,但在使用逻辑与操作时要始终记住它是一个短路操作符;
逻辑或(||):
逻辑或(布尔或OR)运算符由两个竖线 || 表示,有两个操作数,如果其中一个或者两个操作数是真值,它返回一个真值,否则返回假值。如:
var result = true || false;
与&&运算符类似,逻辑或运算符同样是短路操作符,先计算第一个操作数的值,如果为真,则返回;如果为假,则计算第二个操作数的值,并返回该值,也就是说,如果第一个操作数的求值结果为true,就不会对第二个操作数求值了,如:
var found = true;
var result = found || somFun; // 不会抛出错误,因为返回第一个操作数true了。
console.log(result);
逻辑或||运算符最常用的方式是用来从一组备选表达式中选出第一个真值表达式,如可以利用逻辑或的这一行为来避免为变量赋null或undefinded值,如:
var event = e.event || window.event;
// 如果max_width已经定义了,直接使用它;否则在preferences中查找max_width
// 如果还找不到,则使用一个写死的常量500
var max_width;
var preferences = {};
// preferences.max_width = 600;
var max_width = max_width || preferences.max_width || 500;
console.log(max_width);
// 这种惯用的手法通常用于函数体内,用来给参数提供默认值,如:
function copy(o,p){
var p = p || {}; // 如果没有传入p,则创建一个新对象
return p;
}
位操作符:
位操作符用于使用二进制数据进行最底层的运算,即按内存中表示数值的位来操作数值;虽然它不是传统的数学运算,但也可以把它归类于算术运算符,因为它们的操作数是数字并能返回数字;
这些运算符在ES中并不常见,如果对二进制不熟悉的话,可以跳过。
赋值运算符(=):
简单的赋值操作符由等于号=表示,作用就是把右侧的值赋给左侧的变量;
如:var num = 10;
等号左边一般是一个变量或者对象属性(或数组元素),右操作数可以是任意类型的任意值;
等号运算符具有非常低的优先级,通常在一个较长的表达式中用到了一条赋值语句的值的时候,需要补充圆括号以保证正确的运算顺序,如:
var a, b = 0;
console.log((a = b) == 0);
赋值运算符的结合性是从右向左,即,如果一个表达式中出现了多个赋值运算符,运算顺序是从右到左,因此,可以对多个变量赋值:
var i = j = k = 0;
注:但j和k没有使用var声明,其作用域为全局作用域。
复合赋值运算符:如果在等号前再添加其他操作符,就可以完成复合赋值操作;
如:var num = 10; num+=10;
操作符有:+=、-=、*=、/=、%=、>>=、<<=、>>>=、&=、^=、|=
注:+=可用数字或字符串;
注:设计这些操作符的目的就是简化赋值操作;
注:表达式 a op= b 与 a = a op b;是等价的,但第一个a计算一次,第二个a计算二次,因此,在某些时候,两者并不等价,如:
var data = [1,2,3,4];
var i = 1;
data[i++] *= 2;
// data[i++] = data[i++] * 2;
console.log(data);
其他运算符:
typeof运算符:
是一元运算符,返回值表示操作数类型的一个字符串,共六种类型:
undefine、null返回object、true或false返回boolean、任意数字或NaN返回number、string、function、对象(非函数)返回object、任意宿主对象返回由编译器各自实现的字符串;
其有两种语法:typeof value 或 typeof(value);但其不是函数,是运算符;
typeof最常用的用法是写在表达式中,如:
(typeof value == “string”) ? “’” + value + “’” : value
typeof运算会同样在switch语句中非常有用
当操作数是null时,其返回object
其对所有对象和数组都返回object,因此,可以使用它来区别对象和原始值;如果区分对象的类,则需要使用其他的方式 ,如instanceof运算符、class特性和constructor属性;
instanceof运算符:
虽然typeof是个非常有用的工具,但是在检测引用类型的值时,用处不大;有时,想确认一个对象具体是什么类型的对象,就需要使用instanceof操作符了;
instanceof操作符希望左操作数是一个对象,右操作数标识对象的类;如果对象是类的实例,则表达式返回true;其右侧的操作符应当是一个函数
语法:result = variable instanceof constructor
如果变量是引用类型的实例,其会返回true,如:
var num=1;
console.log(num instanceof Number);
var person = new Object();
console.log(person instanceof Object);
var color = new Array();
alconsole.log(color instanceof Array);
var pattern = new RegExp();
console.log(pattern instanceof RegExp);
说明:根据规定,所有引用类型的值都是Object的实例;因此,在检测一个引用类型值和Object构造函数时,instanceof操作符始终会返回true;
in 运算符:
in运算符希望它的左操作数是一个字符或可以转换为字符,右操作数是一个对象,如果该对象拥有一个名为左操作数的属性名,则表达式返回true,如:
var point = {x:1, y:1};
console.log("x" in point); // true
console.log("z" in point); // false
console.log("toString" in point); // true 对象继承的toString()方法
var data = [1,2,3];
console.log("0" in data); // 索引0
console.log(1 in data); // 数字转换为字符串索引
console.log(3 in data); // 没有索引3的元素
delete运算符:
是一元操作符,它用来删除对象属性或数组元素。如:
var o = {x : 1, y : 2};
delete o.x;
console.log("x" in o);
var arr = [1,2,3];
delete arr[2];
console.log(2 in arr);
逗号操作符:
逗号操作符一般用于声明多个变量;
var a=1,b=2,c=3;
我的理解,此处的逗号不应该算是操作符,而是var语句的一部分。
逗号操作符可以在一条语句中执行多个操作,主要用于赋值;在用于赋值时,逗号操作符总会返回表达式中的最后一项,如:
var a = (1,3,5,7);
console.log(a);
其首先计算左操作数,再计算右操作数,最后返回右操作数的值,如:
var num = (i = 2,j = 3,k = i + j);
console.log(num);
// 常见的场景在for循环中:
// 第一个逗号是var语句的一部分
// 第二个逗号是逗号运算符,它将两个表达式(i++,j--)放在一条语句中
for(var i = 0, j = 10; i < j; i++, j--)
console.log(i , j);
- 上一篇:JavaScript类型转换
- 下一篇:js数字(Number)方法汇总
相关推荐
- ES6中 Promise的使用场景?(es6promise用法例子)
-
一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...
- JavaScript 对 Promise 并发的处理方法
-
Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...
- Promise的九大方法(promise的实例方法)
-
1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...
- 360前端一面~面试题解析(360前端开发面试题)
-
1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...
- 前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?
-
Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...
- 最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式
-
看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...
- 前端分享-Promise可以中途取消啦(promise可以取消吗)
-
传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...
- 手写 Promise(手写输入法 中文)
-
前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...
- 什么是 Promise.allSettled()!新手老手都要会?
-
Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...
- 前端面试-关于Promise解析与高频面试题示范
-
Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...
- 宇宙厂:为什么前端离不开 Promise.withResolvers() ?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...
- Promise 新增了一个超实用的 API!
-
在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...
- 一次搞懂 Promise 异步处理(promise 异步顺序执行)
-
PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...
- Promise 核心机制详解(promise机制的实现原理)
-
一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...
- javascript——Promise(js实现promise)
-
1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- ES6中 Promise的使用场景?(es6promise用法例子)
- JavaScript 对 Promise 并发的处理方法
- Promise的九大方法(promise的实例方法)
- 360前端一面~面试题解析(360前端开发面试题)
- 前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?
- 最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式
- 前端分享-Promise可以中途取消啦(promise可以取消吗)
- 手写 Promise(手写输入法 中文)
- 什么是 Promise.allSettled()!新手老手都要会?
- 前端面试-关于Promise解析与高频面试题示范
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)