1. 程式人生 > >JavaScript中加號運算子"+" 運算過程理解

JavaScript中加號運算子"+" 運算過程理解

在JavaScript中二元加法運算子”+”可以對兩個數字或者字串進行連線操作。

1+2=>3
"hello"+" "+"world" => "hello world"
"1"+"2"=>"12"

當兩個運算元都是數字或者都是字串時,得到的結果都是可預期的。但是對於其它情況來說,結果是如何呢?

var arr=[1];
var str="2";
var n=3;
console.log(str+arr);
console.log(n+arr);
console.log(n+null);
console.log(n+undefined);
var obj1={x:1
}; console.log(arr+obj1); var obj2={x:1}; console.log(obj1+obj2); var b1=true; var b2=true; console.log(b1+b2); var b3=new Boolean(false); var b4=new Boolean(false); console.log(b3+b4);

由於情況很多,這裡就不進行逐一列舉。對上面列舉出來的情況,讀者可以先自行思考。在文章的最後給出對應的答案。現在先講一下”+”的處理過程,看看是否和讀者思路一樣。
對於類似上面列舉的情況, “+”運算子要進行一些必要的轉換,並且運算子的行為依賴於型別轉換的結果。加號的轉換規則優先於考慮字串連線,如果其中一個運算元是字串或者轉換為字串的物件,另外一個運算元將會轉換為字串,加法進行字串連線操。如果兩個運算元都不是類字串,那麼將進行算術加法運算。

從技術層面來講,加法的操作表現行為如下:
1) 如果其中一個運算元是物件,則物件會遵循物件到原始值的轉換規則轉換為原始值。(可參考這篇文章:http://blog.csdn.net/u010533180/article/details/54427200)。日期物件通過toString()方法執行轉換,其它物件則通過valueOf()方法執行轉換。由於多數物件都不具備valueOf()方法,因此就會呼叫toString()方法來進行轉換。
2)在進行物件到原始值的轉換後,如果其中一個運算元是字串的話,則另一個運算元也會轉換為字串,然後進行字串的連線操作。
3)否則,兩個運算元都將轉換為數字(或者NaN),然後進行加法操作。

另外需要注意的是加號運算子和字串和數字一起使用的時候,需要考慮加法的結合性對運算的影響。也就是運算結果是依賴運算子的運算順序。

1+2+" hello world"=>"3 helo world"

1+(2+" hello world")=>"12 helo world"

下面來公佈之前提到例子的答案:

var arr=[1];
var str="2";
var n=3;
console.log(str+arr); //21 陣列轉換為對應的字串1
console.log(n+arr);//31 陣列轉換為對應的字串1
console.log(n+null);// 3 null轉換為0
console.log(n+undefined); //NaN undefined轉換為NaN
var obj1={x:1};
console.log(arr+obj1); // 1[object Object] obj1轉換為object
var obj2={x:1};
console.log(obj1+obj2); //[object Object][object Object]
var b1=true;
var b2=true;
console.log(b1+b2); //2 true 轉換為1 進行計算
var b3=new Boolean(false);
var b4=new Boolean(false);
console.log(b3+b4); //0 b3 和b3得到原始值轉換為0

運算子優先順序表格:運算子按照優先順序的不同從高到低排列。

優先順序 運算型別 關聯性 運算子
19 圓括號 n/a ( … )
18 成員訪問 從左到右 … . …
new (帶引數列表) n/a new … ( … )
17 函式呼叫 從左到右 … ( … )
new (無引數列表) 從右到左 new …
16 後置遞增(運算子在後) n/a … ++
後置遞減(運算子在後) n/a … --
15 邏輯非 從右到左 ! …
按位非 從右到左 ~ …
一元加法 從右到左 + …
一元減法 從右到左 - …
前置遞增 從右到左 ++ …
前置遞減 從右到左 -- …
從右到左 typeof …
void 從右到左 void …
從右到左 delete …
14 乘法 從左到右 … * …
除法 從左到右 … / …
取模 從左到右 … % …
13 加法 從左到右 … + …
減法 從左到右 … - …
12 按位左移 從左到右 … << …
按位右移 從左到右 … >> …
無符號右移 從左到右 … >>> …
11 小於 從左到右 … < …
小於等於 從左到右 … <= …
大於 從左到右 … > …
大於等於 從左到右 … >= …
in 從左到右 … in …
從左到右 … instanceof …
10 等號 從左到右 … == …
非等號 從左到右 … != …
全等號 從左到右 … === …
非全等號 從左到右 … !== …
9 按位與 從左到右 … & …
8 按位異或 從左到右 … ^ …
7 按位或 從左到右 … | …
6 邏輯與 從左到右 … && …
5 邏輯或 從左到右 … || …
4 條件運算子 從右到左 … ? … : …
3 賦值 從右到左 … = …
… += …
… -= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
2 yield 從右到左 yield …
從右到左 yield* …
1 展開運算子 n/a ... …
0 逗號 從左到右 … , …

文章參考來源:《JavaScript 權威指南》(原書第六版) 作者 弗蘭納根

相關推薦

JavaScript加號運算子"+" 運算過程理解

在JavaScript中二元加法運算子”+”可以對兩個數字或者字串進行連線操作。 1+2=>3 "hello"+" "+"world" => "hello world" "1"+"2"=>"12" 當兩個運算元都是數字或者都是字串時,得

javascript的n++運算,它的運算過程到底是怎樣的

var n=1; n=n++; console.log(n) //1 之前我一直弄不懂為什麼n++最終沒有起到效果,原來我並沒有弄懂字尾++的運算過程。 先看一道題目: var a=3,b; b=a++*a++; console.log(b) //12 可以看出第一個

JavaScript邏輯運算子(&&、||、!)的優先順序和運算順序

對邏輯運算子只停留在會用的層次,一直沒有專門瞭解其原理。今天得空,好好深究一下,這裡做個筆記,用來參考。 三個邏輯運算子(&&、||、!)優先順序是:!、&& 、||  。 邏輯與(&&)和邏輯或(||)運算子都遵循短路原

JavaScript賦值運算符的使用

結果 color sha 個人 技術分享 img ffffff 操作 ins JavaScript中的賦值運算可以分為簡單賦值運算和復合賦值運算。簡單賦值運算是將賦值運算符(=)右邊表達式的值保存到左邊的變量中;而復合賦值運算混合了其他操作(例如算術運算操作)和賦值操作。例

javascript關系運算符的說明

數據類型的轉換 如果 value 部分 轉換 div gpo 字符串 應用   決定javascript語法的部分叫做ECMAScript,JavaScript的語法相比較java來說寬松了很多,同時也復雜了很多。在ECMAscript中進行關系符運算時,經常會遇到各種類型

個人對於JavaScriptNumber.toFixed()方法的理解

需求:對浮點數進行四捨五入精度獲取。 問題:直接使用Number.toFixed()會出現異常的舍入情況。 原因:計算機浮點數儲存是二進位制,js的Number.toFixed()實際的精度確認規則是四捨六入五成雙,逢四下舍,逢六入一,逢五時,根據瀏覽器核心計算結果也不盡相同。

講解JavaScript對閉包的理解

1、JS中變數的作用域 在理解閉包之前,我們得弄清楚JS中變數的作用域原理,它分為全域性作用域和區域性作用域,它有一個特點就是區域性可以獲取全域性的宣告變數,而全域性卻不能得到區域性宣告的變數,我們先來看一個小例子: var num = 99; function

javascriptnew運算子

建立一個使用者自定義的物件需要兩步: 1、通過編寫函式,來定義物件型別。 2、通過new來建立物件例項。 new的工作流程: 1、建立一個空物件(var obj = {};) 2、使該空物件繼承於建構函式的原型(obj.__proto__ = Foo.pro

JS筆記 | JavaScript運算子

JavaScript中的運算子 1.算數運算子 2.比較運算子 3.邏輯運算子 4.位運算子 5.三目運算子 後記 1.算數運算子 完成基本的算術運算 (arithmetic operato

理解javascriptthis的指向(簡單理解篇)

先列舉幾種常用的this指向: // 全域性下this=windowconsole.log(this==window);this.a = 1;console.log(window.a);// 物件屬性上函式的this指向的是物件objvar obj = {a:1,sayA

JavaScript原型物件的徹底理解

一、什麼是原型 原型是Javascript中的繼承的基礎,JavaScript的繼承就是基於原型的繼承。 1.1 函式的原型物件 ​ 在JavaScript中,我們建立一個函式A(就是宣告一個函式), 那麼瀏覽器就會在記憶體中建立

Markdown顯示矩陣運算過程

發現這個神奇的用法,以後寫部落格就可以很好的演示矩陣乘法了 原文知乎 這裡再分享一個可以把latex轉成圖片的線上網站quicklatex markdown 顯示矩陣 from IPython.display import display,La

JavaScript三元運算子

前端開發幾乎都是動態,一般會遇到很多不確定的判斷,比如需要根據兩種情況給一個標籤做兩種不同的樣式,這個時候我們就需要判斷這兩種情況如果成立是什麼樣式,如果不成立是什麼樣式,下面是我對於三元運算子的一個簡單操作 offorno == true ? divobject.styl

javascript加號(+)操作符的一些神奇作用

javascript是一門神奇的語言,這沒神奇的語言中有一個神奇的加操作符。 常用的加操作符我們可以用來做: 1.加法運算,例如:alert(1+2); ==>3 2.字串連線,例如:alert(“a”+”b”);==>”ab” 高階一點的還有“+=”,也是做以上兩種操作的。 昨天在javasc

javascript 的apply call 的理解

導致 傳遞 rip ant asc spl java array call 1)三者 call()、apply() 都是用來重定義 this 這個對象的! 2)call 、 apply 傳入參數存在差異: apply()方法 接收兩個參數,一個是函數運行的作用域(

關於opengl的三維矩陣平移,矩陣旋轉,推導過程理解 OpenGL計算機圖形學的一些必要矩陣運算知識 glTranslatef(x,y,z)glRotatef(angle,x,y,z)函式詳解

    原文作者:aircraft 原文連結:https://www.cnblogs.com/DOMLX/p/12166896.html     為什麼引入齊次座標的變換矩陣可以表示平移呢? - Yu Mao的回答 - 知乎 https://www.zhihu.com/

理解javascript的焦點管理

javascript document function 管理系統 對焦點 焦點作為javascript中的一個重要功能,基本上和頁面交互都離不開焦點。但卻少有人對焦點管理系統地做總結歸納。本文就javascript中的焦點管理作詳細介紹 焦點元素  到底哪些元素可以獲得焦點呢?默認情況下

javascript對於this指向的再次理解

全局變量 依據 兩個 uem rip 二次 第一個 定義 無法 總所周知,function () {}函數體內的this對象指向的是調用該函數的對象,那麽我們看一下這個例子 <script> var length = 3; function fn ()

JavaScript邏輯運算

view bject 及其 content div 不同 三種 都是 || 一、JavaScript“邏輯”運算符 很多學習 JavaScript的人,容易被 JavaScript 的邏輯運算符的運算規則搞暈。為什麽呢?因為JavaScript

理解javascript的回調函數(callback)【轉】

自己實現 需要 his tab 定義函數 copy 輸入 mil 幹什麽 在JavaScrip中,function是內置的類對象,也就是說它是一種類型的對象,可以和其它String、Array、Number、Object類的對象一樣用於內置對象的管理。因為function