小程序空显示undefined_第11节 Javascript运算符-零点程序员-王唯

关系(比较)运算符:

关系运算符用于测试两个值的关系,根据它们的关系而返回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);  // trueconsole.log(!"blue");  // falseconsole.log(!0);       // trueconsole.log(!NaN);     // trueconsole.log(!"");      // trueconsole.log(!1234);    // false

逻辑非操作也可以用于将一个值转换为与其对应的布尔值;而同时使用两个逻辑非操作符,实际上就会模拟Boolean()转型函数的行为;其中,第一个逻辑非操作会基于无论什么操作数返回一个布尔值,而第二个逻辑非操作则对该布尔值取反,于是就得到了这个值真正的对应的布尔值;当然,最终结果与对这个值使用Boolean函数相同;如:

console.log(!!false);  // falseconsole.log(!!"blue");  // trueconsole.log(!!0);       // falseconsole.log(!!NaN);     // falseconsole.log(!!"");      // falseconsole.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;  // 0var a = 1 && 2;  // 2var a = 1 && 2 && 3;  // 3var a = 1 && 0 && 3; // 0var a = 1 + 1 && 1 - 1; // 0console.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// 如果还找不到,则使用一个写死的常量500var 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);  // trueconsole.log("z" in point);  // falseconsole.log("toString" in point);   // true 对象继承的toString()方法var data = [1,2,3];console.log("0" in data);   // 索引0console.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);
df2997aec39f5058421c8147287d6eba.png

Web前端开发之Javascript-零点程序员-王唯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值