JS判斷對象類型

今天來說講如何判斷 JS 的變量類型。

JS 真不愧是坑爹的語言。數組

先來個懸念~看完你就懂!!!

const a = new String('aa');
const b = 'aa';
console.log(a instanceof String); // true
console.log(b instanceof String); // flase
  • typeof - 最基本的,有六種返回值,用法 typeof xx/typeof(xx).函數

    檢測引用類型值的時候,它的做用不大。prototype

  • instanceof - variable instanceof Object
  • constructor - 寫在紙上的發源地,能夠被強行篡改。
  • Object.prototype.toString.call(element) - 沒法被篡改的祖先,血液裏DNA.code


一. typeof

主要用於區分基本數據類型和對象。對象

使用方法: typeof(variable)/typeof variable
使用結果(6種):ip

  • number
  • boolean
  • string
  • undefined
  • function
  • object

使用示例:element

const a = 3;        // number
const b = 'haha';   // string
const c = true;     // boolean
const d = null;     // object
const e = undefined;// undefined
const f = function() {}   // function

總的來講,typeof對於 數組,RegExp(正則),Date等是無力的。原型鏈


讓咱們來看一下有一塊兒 JS機制 形成的驚天懸疑案???難道 'aa'和'aa'之間還有種族差異??神祕種族! 基本包裝類型!=基本數據類型

實際上還有一種類型叫作:基本包裝類型字符串

[基本包裝類型有:Number/String/Boolean]get

const a = new String('aa');    // object
const b = new Number(3);       // object
const c = new Boolean(true);   // object
const a = 'haha';   // string
const b = 3;        // number
const c = true;     // boolean

實際上呢,這也是基本類型可以擁有方法的緣由。短暫蛻變成爲基本包裝類型 擁有方法 -> 超級賽亞人短暫地得到他們原本沒有的實力???哈哈哈

let s1 = 'haha';         // haha
let s2 = s1.substring(2);// ha

在程序中,其實他們的運行過是這個樣子的!

let s1 = new String('haha');
let s2 = s1.substring(2);
s1 = null;
  • a.建立 String 類型的一個實例
  • b.在實例上調用指定的方法
  • c.銷燬這個實例

    通過上面的處理, 基本的字符串類型就變得 和 對象同樣了

引用類型和基本包裝類型的區別在於對象的生存期。自動建立的基本包裝類型實際上只存在於運行的一瞬間。

由於只有一瞬間,因此實際上他們還不是對象,沒有辦法被添加屬性和方法

let s1 = 'some text';
s1.color = 'red';
console.log(s1.color); // undefined

二. instanceof

它主要用於區分 引用類型。

專業解釋: instanceof運算符用來判斷一個構造函數的prototype屬性所指向的對象是否存在另一個要檢測對象的原型鏈上

const a = new String('aa');
const b = 'aa';
console.log(a instanceof String); // true
console.log(b instanceof String); // flase

上面這個就是咱們開頭的 懸念了,實際上,看了上面 typeof 相關的解釋,這裏你是否是也知道了呢!基本包裝類型(引用類型)和基本數據類型的差異

使用方法: obj instanceof Object

普通實例(找到他們的父類):

function Person(){};
function Coder(){};
var p = new Person();
var s = new Coder();
console.log(p instanceof Person); // true
console.log(s instanceof Coder); // true

這裏是它的一些缺陷的證據(新手跳過)

文藝實例: (這裏能夠先跳過,看完 高程三 再回來看比較好,比較難)

function Person() {}
console.log(Object instanceof Object);     // true

// 第一個Object的原型鏈:Object => Object.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
// 第二個Object的原型:  Object => Object.prototype

console.log(Function instanceof Function); // true

// 第一個Function的原型鏈:Function => Function.__proto__ => Function.prototype
/ /第二個Function的原型:Function => Function.prototype

console.log(Function instanceof Object);   // true

// Function => Function.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
// Object => Object.prototype

console.log(Person instanceof Function);      //true

// Person => Person.__proto__ => Function.prototype
// Function => Function.prototype

console.log(String instanceof String);   // false
// String => String.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
// String的原型鏈:String => String.prototype

console.log(Boolean instanceof Boolean); // false
// Boolean => Boolean.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
// Boolean=>Boolean.prototype

console.log(Person instanceof Person); // false
// Person => Person.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
// Person=>Person.prototype

本意是用來判斷 A 是不是 B 的實例對象。這裏須要注意。instanceof 檢測的是原型。

咱們很容易發現問題(經過基本包裝類型)。它可以檢測出 [] 是 Array 的實例,卻不能檢測出 [] 不是 Object 的實例。

[] instanceof Array // true
[] instanceof Object // true 不該該啊兄弟

var a = new Number(1);
var b = 1;
a instanceof Number; // true
b instanceof Number; // false 不該啊兄弟

所以,咱們用 instanceof 也不能徹底精確的判斷object類的具體數據類型。
同時,咱們發現,使用 Object.prototype.toString.call(x) 時,以上結果都符合預期。

三. constructor

JavaScript中,全部對象都有一個 constructor 屬性,它引用初始這個對象的構造函數

constructor就像是寫在 紙上 的種族,只要是在紙上的東西,均可能是能夠改的,因此,它並不穩定。

constructor 是個屬性,在 JS 中,大多數屬性是能夠被修改的。

// 如下代碼運行於 Node v10 環境下
var a = [1, 2];
var b = new Array(3);
var c = 'test';
var d = new String('test');

console.log(d.constructor === String); // true
console.log(c.constructor === String); // true
console.log(b.constructor === Array);  // true
console.log(a.constructor === Array);  // true

也許你會以爲無厘頭?誰會這麼改,可是:人們有這麼作的可能性,咱們就應該防範。

var d = new String('test');
String.prototype.constructor = "I'm change.";
console.log(d.constructor); // I'm change
console.log(d.constructor === String); // false

四. 無敵的判斷者: Object.prototype.toString.call(element) - 這是源頭的源頭。

constructor比如咱們人類的發源地,好比 亞洲。而這個呢,至關因而地球。

它和下者的差距在這裏: https://www.zhihu.com/question/50934612

var d = new String('test');
console.log(Object.prototype.toString.call(d)); // [object String]
var b = new Array(3);
console.log(Object.prototype.toString.call(b)); // [object Array]

complete.

相關文章
相關標籤/搜索