【面試篇】JS數據類型及判斷

概念

首先明確ECMAscript中的數據類型分爲兩種:基本類型和引用類型javascript

  • 基本類型:即簡單的數據段,都是按值訪問的,即將一個基本類型的數據賦值給另一個變量,是經過將原數據拷貝一份賦值的,兩變量之間互不影響。如圖:
    clipboard.pngjava

  • 引用類型:即保存在內存中的對象,按引用訪問,即將一個引用類型的地址賦值給另外一個變量,當該變量改變時,原變量也會隨之改變。如圖:
    clipboard.png程序員

分類

  • 基本類型有:Undefined,Null,Boolean,Number,String;數組

  • 引用類型:
    1.第一類:原生對象(ECMAScript自己自帶對象,有程序員在腳本運行環境中建立來使用):app

object,Array,Date,RegExp,Function,基於基本類型還衍生出來了三個包裝類型:Boolean,Number,String,每當咱們讀取一個基本數據類型的實例時,後臺都會建立一個對應的基本包裝類型,從而使咱們可使用不是對象的基本類型調用相應的方法。
2.第二類內置對象(JS語言提供的不依賴於執行宿主的對象,如Global,Math)。
3.宿主對象(JS語言提供的任何依賴宿主環境的對象,如IE中的window,WS中的WScript實例,以及任何用戶建立的類)函數

  • 基本包裝類型和引用類型的區別
    使用new操做符建立的引用類型的實例,在執行流離開當前做用域以前都一直保存內存中,而自動建立的基本包裝類型的對象,只存在於一行代碼執行的瞬間,而後當即被銷燬,即咱們不能在運行時爲基本類型值添加屬性和方法。如圖:clipboard.png測試

typeof和Object.prototype.toString()辨析

  • typeof會判斷數據類型會返回一個字符串,以下圖this

// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 儘管NaN是"Not-A-Number"的縮寫,意思是"不是一個數字"
typeof Number(1) === 'number'; // 不要這樣使用!

// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof返回的確定是一個字符串
typeof String("abc") === 'string'; // 不要這樣使用!

// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 不要這樣使用!

// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';

// Undefined
typeof undefined === 'undefined';
typeof blabla === 'undefined'; // 一個未定義的變量,或者一個定義了卻未賦初值的變量

// Objects
typeof {a:1} === 'object';

// 使用Array.isArray或者Object.prototype.toString.call方法能夠從基本的對象中區分出數組類型
typeof [1, 2, 4] === 'object';

typeof new Date() === 'object';

// 下面的容易使人迷惑,不要這樣使用!
typeof new Boolean(true) === 'object';
typeof new Number(1) ==== 'object';
typeof new String("abc") === 'object';

// 函數
typeof function(){} === 'function';
typeof Math.sin === 'function';

由以上結果可知typeof在數組,正則,日期,對象上的判斷並很差,都是返回object
由此能夠引出另外一個判斷方法Object.prototype.toString();toString()方法返回一個描述某對象的字符串,若是此方法在自定義的對象中未被覆蓋,則toString()返回"[object type]",其中type是對象類型。在使用toString()方法檢測對象類型時,經常使用Object.prototype.toString.call()Object.prototype.toString.apply()來檢測,以下代碼:spa

var toString = Object.prototype.toString;
toString.call(new Date);//[object Date]
toString.call(new String);//[object String]
toString.call(Math);//[object Math]
toString.call(undefined);//[object Undefined]
toString.call(null);//[object Null]

牛刀小試

題一:prototype

var y = 1, x = y = typeof x;
x;

//out:"undefined",由於x變量提高,故typeof時,不爲null

題二:

(function f(f){
    return typeof f();
  })(function(){ return 1; });

//out:"number",由於在當即執行函數裏將function(){return 1}當作實參傳遞給了形參f,故當f執行後返回1,typeof 1便返回"number"

題三:

var foo = {
    bar: function() { return this.baz; },
    baz: 1
  };
  (function(){
    return typeof arguments[0]();
  })(foo.bar);

//out:"undefined",考察this指針,除了ES6的箭頭函數之外,this指針永遠指向函數執行時的上下文對象,在此處傳入arguments[0]中,this指向window對象,故爲undefined.

clipboard.png
//分組選擇符?難道這不是逗號表達式麼?恩,回頭細究~

題六:這個比較好玩

var x = 1;
  if (function f(){}) {
    x += typeof f;
  }
  x;//

//out:"1undefined",本覺得會是1function呢,結果看了解析才知道,是由於javascript語言規範的問題,在條件判斷中加入函數聲明,會返回true,然而javascript引擎在搜索時找不到該函數,因此結果爲1undefined

題七:

(function(foo){
    return typeof foo.bar;
  })({ foo: { bar: 1 } });

//out:undefined ,噗,當作"numberl"了,函數裏的foo指向整個對象,然而整個對象並無bar屬性

instanceof辨析

indtanceof用來判斷某個構造函數的prototype屬性是否存在於要檢測對象的原型鏈上,以下:

// 定義構造函數
function C(){} 
function D(){} 

var o = new C();
// true,由於 Object.getPrototypeOf(o) === C.prototype
o instanceof C; 
// false,由於 D.prototype不在o的原型鏈上
o instanceof D; 
o instanceof Object; // true,由於Object.prototype.isPrototypeOf(o)返回true
D.prototype = new C(); // 繼承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

ps:prototypeObj.isPrototypeOf(object)用於測試一個對象是否存在於另外一個對象的原型鏈上,object爲被搜索原型鏈的對象

ps2:參考文獻中有這樣一個警示,然而我沒看懂...明日回更,歡迎評論指點。
clipboard.png

相關文章
相關標籤/搜索