成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

連等賦值a.x = a = {n:2} 和a = a.x = {n:2}一樣嗎?

開發 項目管理
假如你在面試中被問到,不知道能不能給面試官留下機敏過人的好印象呢?如果你也感興趣,那就繼續往下看吧。

[[424213]]

前言

最近有空看了一點《js 高級程序設計》中變量和內存的章節,對變量和內存問題做了總結整理,其中包含了面試中一些老生常談的問題,并且穿插了一些看似簡單卻一不小心就掉坑里的小代碼題,假如你在面試中被問到,不知道能不能給面試官留下機敏過人的好印象呢?如果你也感興趣,那就繼續往下看吧。

本文涉及以下知識點

第一部分 變量

一 基礎數據類型

8 種。undefined、Null、Boolean、Number、String、symbol、bigInt、object。

1.1 基本類型

7 種。undefined、Null、Boolean、Number、String、symbol、bigInt。其中兩種較為特殊的稍作解釋。

symbol

每個從Symbol()返回的 symbol 值都是唯一的。一個 symbol 值能作為對象屬性的標識符;這是該數據類型僅有的目的。

  1. Symbol('1') == Symbol('1') // false 

作為構造函數來說它并不完整,因為它不支持語法:new Symbol()。

  1. Symbol(1) //Symbol(1) 
  2. new Symbol(1) // Uncaught TypeError: Symbol is not a constructor 

Q1. 如果一個對象的 key 是用 Symbol 創建的,如何獲取該對象下所有的 key ,至少說出兩種?

A1. Object.getOwnPropertyNames Object.getOwnPropertySymbols 或者 Reflect.ownKeys

Q2. typeof Symbol 和 typeof Symbol()分別輸出什么?

A2.

  1. typeof Symbol //"function" 
  2.  
  3. typeof Symbol() //"symbol" 

bigInt

BigInt 是一種數字類型的數據,它可以表示任意精度格式的整數。目的是安全地使用更加準確的時間戳,大整數 ID 等,是 chrome 67 中的新功能。Number類型只能安全地表示-9007199254740991 (-(2^53-1)) 和9007199254740991(2^53-1)之間的整數,超出此范圍的整數值可能失去精度。

  1. 9007199254740991 //9007199254740991 
  2. 9007199254740992 //9007199254740992 
  3. 9007199254740993 //9007199254740992 !! 

創建BigInt在整數的末尾追加 n,或者調用BigInt()構造函數。

  1. 9007199254740993n //9007199254740993n 
  2. BigInt('9007199254740993') //9007199254740993n 
  3. BigInt(9007199254740993) //9007199254740992n !! 

BigInt 和 Number不是嚴格相等的,但是寬松相等的。

  1. 9n == 9  
  2. //true 
  3. 9n === 9  
  4. //false 

1.2 引用類型

object 里面包含的 function、Array、Date、RegExp。

1.3 null 和 undefined 的區別

undefined讀取一個沒有被賦值的變量,null定義一個空對象,是一個不存在的對象的占位符

null和undefined轉換成 number 數據類型結果不同。null轉成0,undefined轉成NaN

  1. new Number(null) //Number {0} 
  2.  
  3. new Number(undefined) //Number {NaN} 

二 判斷數據類型

2.1 typeof

只適用于判斷基本數據類型(除null外)。null,表示一個空對象指針,返回object。對于對象來說,除了 function 能正確返回 function,其余也都返回object。

  1. var a;  
  2. console.log(a);//undefined 
  3. console.log(typeof a); //undefined 
  1. typeof typeof 1 //"string" 

2.2 instanceof

判斷 A 是否是 B 的實例,A instanceof B,用于判斷已知對象類型或自定義類型。

  1. function Beauty(name, age) { 
  2.   this.name = name
  3.   this.age = age; 
  4. var beauty = new Beauty("lnp", 18); 
  5. beauty instanceof Beauty // true 

Q1.

  1. Object instanceof Function // true 
  2. Function instanceof Object // true 
  3. Object instanceof Object // true 
  4. Function instanceof Function // true 
  • instanceof 能夠判斷出 [] 是Array的實例,但它認為[ ] 也是Object的實例,因為它內部機制是通過對象的原型鏈判斷的,在查找的過程中會遍歷左邊變量的原型鏈,直到找到右邊變量的prototype,找得到就返回true。
  • instanceof無法判斷通過字面量創建的Boolean,Number,String類型,但是可以判斷經new操作符創建的實例。
  • instanceof可以判斷通過字面量創建的引用類型Array,Object。

2.3 constructor

  • constructor 屬性返回對創建此對象的數組函數的引用。

constructor 不能用于判斷undefined 與 null,因為它們沒有構造函數。

實用場景小程序中,WXS 不支持使用 Array 對象,因此我們平常用于判斷數組類型[] instanceof Array就不能使用了,而typeof []輸出結果是object,并不能滿足要求。這個時候就可以用constructor 屬性進行類型判斷:[].constructor === Array //true。

2.4 toString

Object.prototype.toString.call()判斷某個對象屬于哪種內置類型。是判斷數據類型最嚴謹通用的方法。

  • 判斷基本類型
  1. Object.prototype.toString.call(null); // "[object Null]" 
  2. Object.prototype.toString.call(undefined); // "[object Undefined]" 
  3. Object.prototype.toString.call(true);// "[object Boolean]" 
  4. Object.prototype.toString.call(123);// "[object Number]" 
  5. Object.prototype.toString.call(“lnp”);// "[object String]" 
  • 判斷原生引用類型
  1. // 函數類型 
  2. Function Beauty(){console.log(“beautiful lnp”);} 
  3. Object.prototype.toString.call(Beauty);//”[object Function]” 
  1. // 日期類型 
  2. var date = new Date(); 
  3. Object.prototype.toString.call(date);//”[object Date]” 
  1. // 數組類型 
  2. var arr = [1,2,3]; 
  3. Object.prototype.toString.call(arr);//”[object Array]” 
  1. // 正則表達式 
  2. var reg = /^[\d]{5,20}$/; 
  3. Object.prototype.toString.call(arr);//”[object RegExp]” 
  • 判斷原生 JSON 對象
  1. var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON); 
  2. console.log(isNativeJSON);//輸出結果為”[object JSON]”說明 JSON 是原生的,否則不是 

Q1.

  1. ({a:1}).toString() //返回什么 
  2.  
  3. ({a:1}).__proto__ === Object.prototype 
  4. ({a:1}).toString() // [object Object] 
  • 對于 Object 對象,直接調用 toString() 就能返回 [object Object] 。而對于其他對象,則需要通過call來調用才能返回正確的類型信息。

小結

第二部分 內存

一 堆/棧

基本類型保存在棧內存,引用類型的值保存在堆內存,存儲該值的地址(指針)保存在棧內存中,這是因為保存在棧內存的必須是大小固定的數據,而引用類型的大小不固定。

堆和棧的區別

二 深淺拷貝

2.1 數據類型的拷貝

Q1. 以下代碼輸出什么?

  1. 1 == 1; 
  2. [] == []; //? 
  3. {} == {}; //? 

A1. 答對了嗎?

  1. 1 == 1; //true 
  2. [] == []; //false 
  3. {} == {}; //false 

原因:原始值的比較是值的比較,值相等時它們就相等(),值和類型都相等時它們就恒等(=) 對象(數組)的比較是引用的比較,即使兩個對象包含同樣的屬性及相同的值,它們也是不相等的。

基本類型

圖片復制的時候,在棧內存中重新開辟內存,存放變量 age2,所以在棧內存中分別存放著變量 age、age2 各自的值,修改時互不影響。

引用類型

復制的時候,只復制了棧內存中存儲的指針,Beauty 和 Beauty2 的指針指向的是堆內存中的同一個值。

連等賦值 a.x = a = {n:2}

理解了嗎?那么題目中的問題就要來嘍!準備好了嗎?請看下面一小段代碼... ...

  1. var a = {n:1};  
  2. var b = a;  
  3. a.x = a = {n:2}  
  4. console.log(a.x);  
  5. console.log(b.x);  
  6. console.log(a);  
  7. console.log(b);  
  8. // 以上代碼輸出什么? 

答(猜)對了嗎?

  1. undefined  
  2. {n: 2} 
  3. {n: 2} 
  4. {n: 1, x: {n: 2}} 

解析我們先來還原一下這道題的執行過程。首先var a = {n:1}; 時,為變量 a 在堆內存中開辟了一塊內存空間。圖片

當var b = a; 時,將變量 b 的指針指向了堆內存中與 a 相同的內存空間。

a.x = a = {n:2}中由于“.”是優先級最高的運算符,先計算a.x,a.x尚未定義,所以是undefined。

然后賦值運算按照從右往左的順序解析,執行a = {n:2},a(一層變量)被重新賦值,指向一塊新的內存空間。

此時a.x,是指堆中已存在的內存 {n:1 x:undefined }的x屬性,可以把a.x當作一個整體A,A的指向此時已經確定了,所以a的指向并不會影響a.x,執行a.x = a,則是把{n:2}賦值給{n:1 x:undefined }的x屬性。

到這里函數執行完畢,那我們來看(a.x); (b.x); (a); (b); 分別指向什么就 一目了然了。

這個題考察以下 2 個知識點:

  • object 類型數據在堆棧中的存儲和賦值
  • Javascript 中運算符的優先級

同理,來看一下把a.x = a = {n:2} 換成a = a.x = {n:2}呢?

  1. var a = {n:1};  
  2. var b = a;  
  3. a = a.x = {n:2} 
  4. console.log(a.x);  
  5. console.log(b.x);  
  6. console.log(a);  
  7. console.log(b); 

答案是一樣的,原理同上。

2.2 深拷貝和淺拷貝區別

  • 淺拷貝 只復制指向某個對象的指針,而不復制對象本身,拷貝后新舊對象指向堆內存的同一個值,修改新對象對改變舊對象。
  • 深拷貝 不但對指針進行拷貝,也對指針指向的值進行拷貝,也就是會另外創造一個一模一樣的對象副本,新對象跟舊對象是各自獨立的內存空間,修改新對象不會影響舊對象。

2.3 深拷貝和淺拷貝優劣,常用場景

  • 深拷貝好處 避免內存泄漏:在對含有指針成員的對象進行拷貝時,使拷貝后的對象指針成員有自己的內存空間。
  • 淺拷貝好處 如果對象比較大,層級也比較多,深拷貝會帶來性能上的問題。在遇到需要采用深拷貝的場景時,可以考慮有沒有其他替代的方案。在實際的應用場景中,也是淺拷貝更為常用。

2.4 實現深淺拷貝的方法和其弊端

深拷貝方法:

JSON.parse()與 JSON.stringify() 針對純 JSON 數據對象,但是它只能正確處理的對象只有 Number, String, Boolean, Array, 扁平對象。

  1. let obj = {a:{b:22}}; 
  2. let copy = JSON.parse(JSON.stringify(obj)); 
  • postMessage
  • 遞歸
  • lodash

淺拷貝方法:

  • object.assign
  • 擴展運算符...
  • slice
  • Array.prototype.concat()

2.5 總結

深淺拷貝只針對 Object, Array 這樣的復雜對象,淺拷貝只復制一層對象的屬性,而深拷貝則遞歸復制了所有層級。

第三部分 垃圾收集

javaScript 具有自動垃圾收集機制,也就是說,執行環境會負責管理代碼執行過程中使用的內存。

那么,是不是我們就可以不管了呢?當然不是啊。開發人員只是無需關注內存是如何分配和回收的,但是仍然要避免自己的操作導致內存無法被跟蹤到和回收。

垃圾收集

首先,我們來了解一下 js 垃圾回收的原理。在局部作用域中,函數執行完畢,局部變量就沒有存在的必要了,因此可以釋放他們的內存以供將來使用。這種情況,js 垃圾回收機制很容易做出判斷并且回收。垃圾收集器必須跟蹤哪個變量有用哪個沒用,把不用的打上標記,等待將來合適時機回收。

js 的垃圾收集機制有兩種,一種為標記清除,一種為引用計數。

所以對于全局變量,很難確認它什么時候不再需要。

內存泄漏 vs 堆棧溢出

什么是內存泄漏和堆棧溢出,二者關系是什么?

內存泄露是指你不再訪問的變量,依然占據著內存空間。堆棧溢出是指調用即進棧操作過多,返回即出棧不夠。關系:內存泄漏的堆積最終會導致堆棧溢出。

內存泄漏會導致什么問題?

運行緩慢,崩潰,高延遲

4 種常見的內存泄露陷阱

  • 意外的全局變量,這些都是不會被回收的變量,特別是那些用來臨時存儲大量信息的變量(除非設置 null 或者被重新賦值)
  • 定時器未銷毀
  • DOM 以外的節點引用
  • 閉包(閉包的局部變量會一直保存在內存中)

2 種常見的堆棧溢出

  • 遞歸
  • 無限循環

內存泄漏避免策略

 

  • 減少不必要的全局變量,或者生命周期較長的對象,及時解除引用(將不再使用的全局對象、全局對象屬性設置為 null)
  • 注意程序邏輯,避免“死循環”之類的
  • 避免創建過多的對象
  • 減少層級過多的引用

劉妮萍: 微醫前端工程師。養魚養花養狗,熬夜蹦迪喝酒。出走半生,歸來仍是三年前端工作經驗。

 

責任編輯:武曉燕 來源: 微醫大前端技術
相關推薦

2010-08-25 17:56:23

N+XUPS

2021-04-15 20:44:29

辦公

2013-12-17 10:34:54

WindowsiOSOS X

2013-10-24 09:18:55

OS XOS X Maveri

2011-12-12 10:40:08

Cocos2d-X游戲開發開發環境

2010-07-29 08:56:53

DB2基本操作指令

2014-05-05 15:20:07

集群配置Web開發

2020-03-02 10:56:41

辦公電腦疫情

2017-06-08 11:00:09

HDFSHadoopYARN

2013-05-22 15:49:46

2020-10-20 18:42:17

Vue 3.0vue2.x數據

2022-11-02 07:39:53

CPU計算機C 語言

2020-11-12 08:30:38

Java微服務Go

2021-01-14 16:00:52

VRVR電影3D電影

2012-04-17 10:06:08

cocos2d-x

2012-04-17 10:59:31

cocos2d-x

2012-04-17 12:38:46

cocos2d-x

2012-04-17 12:44:38

cocos2d-x

2017-04-26 14:02:18

大數據數據分析Excel

2023-01-18 08:10:34

Web3Web2JavaScript
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人欧美一区二区三区在线播放 | 亚洲视频免费在线播放 | 人人干人人干人人 | 久草免费视 | 国产高清免费视频 | 国产视频久久 | 久久久久香蕉视频 | 成人av播放 | 日韩高清成人 | 久久不卡| 亚洲欧美成人 | 亚洲欧美中文日韩在线v日本 | 伊人超碰在线 | 成人亚洲精品久久久久软件 | 毛片免费在线 | 久久国产精品色av免费观看 | 亚洲精品丝袜日韩 | 日本一区二区三区在线观看 | 欧美精品 在线观看 | 亚洲欧美激情四射 | 成年网站在线观看 | 91视视频在线观看入口直接观看 | 亚洲精品在线视频 | 国产视频久 | 天天成人综合网 | 午夜在线影院 | 亚洲精品在线视频 | 欧美片网站免费 | 久久这里只有精品首页 | 在线观看中文字幕 | 国产一区黄色 | 欧美激情综合 | 成人在线免费视频观看 | wwwxxx国产 | 一级免费毛片 | av一二三区| 精品视频一区二区三区 | 精品国产一区二区在线 | 久久久久国产精品一区二区 | 一区二区在线 | 久久国产综合 |