理解Javascritp中的"引用"

Author: bugall
Wechat: bugallF
Email: 769088641@qq.com
Github: https://github.com/bugalljavascript

一: 函數中的引用傳遞

咱們看下下面的代碼的正確輸出是什麼java

function changeStuff(a, b, c)
{
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num); // 10
console.log(obj1.item); // changed    
console.log(obj2.item); // unchanged

在javascript中除了基礎類型採用的是值(值類型有哪些)傳遞,而對象採用是引用傳遞。這就好理解爲何a的值沒有被修改。git

那爲何obj1的值修改了,可是obj2的值卻沒有被覆蓋?當咱們調用changeStuff函數的時候,參數b,c的值分別是obj1,obj2的引用。github

當咱們去修改的b的值的時候,由於b->obj1的引用關係沒有變,因此實際修改的是obj1的值。可是參數c的狀況就不一樣了,由於咱們在函數中對c進行了引用的從新綁定,c = {item: "changed"} 這時候的c中的對象引用已經改變,這裏要清楚引用和指針的關係。segmentfault

二: 邏輯判斷中的引用

一般咱們會把==理解爲值相同,把===理解爲值相同且類型相同。函數

可是這種理解不是徹底準確的。0=='' //true,直觀理解上0怎麼會等於''空字符串呢?由於在作==邏輯判斷的時候js會把==兩邊的值作類型轉換,而後再比較。spa

另外在javascript中比較奇葩的就是關於null,我很難理解爲何null支持比較呢?好比在SQL中咱們是不能對null值直接比較的,一般都會使用is null or is not null來作判斷。翻譯

若是咱們把===理解爲值相同,且類型相同那麼就沒法理解[1] === [1] // false的狀況,由於[1]值相同,類型也相同。指針

咱們應該怎麼理解===

===不會判斷值是否相同,只會判斷===左右兩邊的變量保存的引用地址是否相同,咱們一塊兒看下例子code

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false 由於a,b的引用不一樣,
// 或者理解爲a,b引用的對象在堆上不是同一個對象。

var ac_eq = (a === c); // true 由於a保存了一份對象的引用,
// `c=a` c會把a的值copy一份,這是a,c的值(保存對象的引用)相同。 

其實對於一個變量來講,包含了`左值`和`右值` 後面我會整理文章

相似的例子

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false type)
var ac_eq = (a === c); // true
var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false 
var ac_eq = (a === c); // true

總結===的三種狀況

對於整型 (numbers):
a === b // 若是值相同返回true

對於引用類型來講:
a === b // 若是a,b保存的是同一個對象的引用返回true

對字符串來講:
a === b // 左右兩邊的字符相同返回true

var1 == var2 結果圖
圖片描述

三: const中的引用

咱們首先看下官方的定義:

constant cannot change through re-assignment
constant cannot be re-declared

簡單翻譯就是:const定義的變量不能被從新定義,不能被從新賦值。
const 只能確保定義的變量的引用地址不會被改變。可是若是引用指向的
是一個對象的話,你是能夠對對象裏的值進行修改的,由於沒有改變對象
自身的地址。

const x = {};
x = {foo: 'bar'}; // error - re-assigning

const y = ['foo'];
const y = ['bar']; // error - re-declaring

const foo = 'bar'; 
foo = 'bar2';       // error - can not re-assign
var foo = 'bar3';   // error - already declared
function foo() {};  // error - already declared

可是對於值的修改是容許的

const x = {};

x.foo = 'bar';

console.log(x); // {foo : 'bar'}

const y = [];

y.push('foo');

console.log(y); // ['foo'];
相關文章
相關標籤/搜索