一些有意思的JavaScript代碼片段

Javascript是一門很靈活的語言,我們可以使用它動(dòng)態(tài)地實(shí)現(xiàn)各種各樣的功能。但是動(dòng)態(tài)帶來便利的同時(shí),也存在一些令人費(fèi)解的行為,稍不注意就會(huì)進(jìn)入誤區(qū)一個(gè)接著一個(gè)的坑。雖然我使用JavaScript的時(shí)間還不算長,也是遇到了一些有意思的場景,一開始百思不得其解,弄清楚之后又讓我哭笑不得。現(xiàn)在就來跟大家一起分享一下。

語法糖帶來的淺拷貝

先來預(yù)測一下下面代碼的輸出內(nèi)容:

const user = {
  name: 'zong',
  location: {
    city: 'Shanghai',
    state: 'Shanghai'
  }
};
const copy = Object.assign({}, user);
// 或者
// const copy = { ...user };
copy.location.city = 'Suzhou';
console.log('original: ', user.location);
console.log('copy:', copy.location);

輸出結(jié)果應(yīng)該是:

original:  {
  city: 'Shanghai',
  state: 'Shanghai'
}
copy: {
  city: 'Shanghai',
  state: 'Shanghai'
}

咦?為什么操作復(fù)制的對(duì)象會(huì)修改原來的對(duì)象呢?這是因?yàn)?code>Object.assign跟spread operator只做了一層淺拷貝,這意味著只有對(duì)象的第一層屬性會(huì)被復(fù)制,如果某個(gè)屬性是個(gè)嵌套的對(duì)象,那么只有引用會(huì)被復(fù)制,所以我們操作修改的對(duì)象的屬性影響到了原來的對(duì)象。

所以在我們這個(gè)例子中copylocation屬性將仍然指向原來user對(duì)象對(duì)應(yīng)的location屬性。

JavaScript從右向左賦值的行為

function display() {
  var a = b = 10;
}

display();

console.log('b', typeof b === 'undefined');
console.log('a', typeof a === 'undefined');

輸出是:

b false
a true

這是因?yàn)镴avaScript賦值操作符是從右向左的,這意味著我們的賦值操作也是從右向左來的,手先b會(huì)被賦值10,然后它被賦給了a。

所以:

function display() {
  var a = b = 10;
}

等同于:

function display() {
  b = 10;
  var a = b;
}

所以b沒有用var聲明成了一個(gè)全局變量,所以在外部可以被訪問到,而a只是個(gè)局部變量,所以外部會(huì)打印出a === undefinedtrue。

但是如果上面的代碼在嚴(yán)格模式中執(zhí)行的話,情況又不一樣了,由于嚴(yán)格模式不允許創(chuàng)建全局變量所以這段代碼會(huì)直接拋出異常。

提升

var num = 8;

var display = function () {
  console.log(num);
  var number = 20;
};

display();

猜猜這里的輸出結(jié)果是什么?它不是8而是undefined,這又是為什么?

這是因?yàn)镴avaScript里面有個(gè)現(xiàn)象叫提升。提升是JavaScript中把變量聲明移到當(dāng)前作用域最頂部的一種行為。

所以上面的代碼可以轉(zhuǎn)換成如下:

var num = 8;

var display = function () {
  var num;
  console.log(num);
  num = 20;
};

display();

我們可以看到只有聲明被移到了函數(shù)的最頂端,而賦值操作還在原地,所以這邊num由于還未賦值會(huì)打印出undefined

delete的作用對(duì)象

const num = 1;

const result = (function () {
  delete num;
  return num;
})();

console.log(result);

這邊的代碼不會(huì)報(bào)出任何錯(cuò),因?yàn)槲覀兪窃?code>number類型上使用的delete,它還是會(huì)打印出1。

The delete操作符被用來刪除一個(gè)對(duì)象的屬性,在這兒num并不是一個(gè)對(duì)象所以它會(huì)返回這個(gè)變量對(duì)應(yīng)的值,也就是1。

const num = 1;

const result = (function (num) {
  delete num;
  return num;
})(10);

console.log(result);

上面的代碼將輸出10。

這邊我們把10作為參數(shù)傳給函數(shù),同樣地delete在這里對(duì)原始類型也不起作用,所以會(huì)照常打印出10。

好啦,今天的分享就到這里啦,主要是在使用JavaScript的過程中可能會(huì)經(jīng)常遇到的一些細(xì)節(jié)問題,希望能給大家?guī)硪粊G丟的收獲,happy coding~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容