Javascript 进阶 3-6 优先性及相依性

http://img2.58codes.com/2024/20121770JKsfyBX2zH.jpg

今天要讲的是 优先性 及 相依性

优先性

首先所谓 优先性 ,就是只说我们运算子在运行的时候,会先进行哪种运算。而图片上面提到的 优先性较高的运算子会成为优先性较低的运算子的运算元 这个概念指的是,运算子是一种表达式,只要是表达式,就会有一个 回传的值 。而这个回传的值,会再成为 优先姓较低的运算子 的 运算元 (好饶口~)

接下来我们就来看个实例

var a = 2 * 2 + 2 * 3;console.log(a);

看到这样的运算,有学过数学的人就知道,先加减后乘除,所以照这个观念,我们可以算出 a = 10 的结果。

没错,答案是 10 ,而这里先加减后乘除的观念就是 运算子的优先性。

我们可以从这个 MDN的连结查看各种运算子的优先性

点开以后直接看到表格的部分

http://img2.58codes.com/2024/20121770xSdkg2idAD.jpg

乘法跟除法的优先性都是15,大于加法跟减法的13,所以会优先执行乘除之后再执行加减,而别忘了, = 也是运算子的一种喔,只是因为他的优先性很低 只有 3 尔以,所以最后通常算完的结果才会执行这个运算子。

http://img2.58codes.com/2024/20121770GKVdLpc0YP.jpg

相依性

再来介绍相依性,相依性就是运算子执行的方向,通常分为 从左至右 以及 从右至左,少部分是 无相依性 。

这边 加减乘除 4 个都是属于 从左至右 ,而赋值的 = 则是属于 从右至左。

好~有了上面这些观念以后,我们就可以知道, a 透过 运算子优先序 以及 运算子相依性,他的运算逻辑如下

// 先乘除 相依性左到右2 * 2 = 42 * 3 = 6// 加减 相依性左到右4 + 6 = 10// 赋值 相依性右到左a = 10

那再来提一些特别的案例

console.log(1 < 2 < 3); // true

这个好像还蛮符合预期的。

但当反过来的时候

console.log(3 > 2 > 1); // false

为什么会这样呢????

让我们来解析一下

// 小于大于的符号,优先度一样是11,那再来就是先相依性的顺序都为 从左至右,但这里必须拆开来看3 > 2 // 回传 true, true 在javascript 中会自己型别转换为 1, 相反 false 就是转换成 0。// 所以就变成1 > 1 // 这边当然是回传 false

喔~所以我们的多运算子判断式,还是会依照相依性的方向,两个运算元一个运算子一组的进行运算,因为这样的运算结果的回传值成为接下来运算子的运算元,应证了一开始图片上所讲的观念喔!

有兴趣的人也可以照着上面的观念,自己推导看看 console.log(1 < 2 < 3); 为什么会是 true。

那再来看另一个例子

var a = 1;var b = 2;a = b = 3;console.log(a, b); // 3 , 3

这个结果其实也蛮符合预期的吧~

虽然a, b分别在一开始的时候赋予了不同的值,但最后都被指派成3

顺序依照目前的理解是

// 因为 = 是由右边到左边的相依性,所以会是这样b = 3;a = b;

所以自然而然,a跟b就是3了阿~

但是,虽然结果是对的,观念理解却是错的喔!!!!!

怎么说呢? 我们先在来看一个例子喔!

var b = {};Object.defineProperty(b, 'a', {    value: 2,    writable: false});

上述这个code是指说,我现在宣告一个物件叫b,我要在这个物件b里面,新增一个属性,他的keyname是a,并且a的值指派是数字2,更重要的是这个值是不能被複写的。

所以没有办法透过 b.a = 3; 来複写这个值。

var b = {};Object.defineProperty(b, 'a', {    value: 2,    writable: false});b.a = 3; // 2console.log('b.a', b.a);var a = 3;a = b.a = 1;

所以这段程式码执行的结果应该b.a = 2,因为他不会被複写。

但是下方的 a = b.a = 1; 大家觉得 a 的结果会是多少?

这里直接公布答案喔,答案是1 ,为甚么呢,因为同样,优先性一样高,依照相依性,由右到左来分析

b.a = 1;// 这里虽然b.a的值还是2,但这个表达式会 回传的值 其实是1喔// 而重点是回传的值会再次成为其他运算子的运算元,所以接下来的表达式是等同于a = 1(b.a = 1的回传值)// 所以 a 才等于 1喔!!

就是这个精神,所以如果今天在更複杂改成

var b = {};Object.defineProperty(b, 'a', {    value: 2,    writable: false});Object.defineProperty(b, 'b', {    value: 3,    writable: false});b.a = 3; // 2console.log('b.a', b.a);var a = 3;a = b.b =b.a = 1;

这样最后a的值呢?还是会是 1喔!

但是b.a也还是2 b.b也还是3喔!

最后再回到

var a = 1;var b = 2;a = b = 3;console.log(a, b); // 3 , 3

所以这边的顺序应该是因为

b = 3; // 回传 3a = 3(b = 3的回传值);

所以这样a跟b才都是等于3,并非是因为a取得了b的值,所以才等于3。

这篇可能理解上要稍微想过一下,可以想清楚以后在进入下一篇文章喔~汪汪


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章