Skip to content

Instantly share code, notes, and snippets.

@fluency03
Last active February 7, 2019 13:20
Show Gist options
  • Save fluency03/4f2cb7ce804178b43561908f367b213d to your computer and use it in GitHub Desktop.
Save fluency03/4f2cb7ce804178b43561908f367b213d to your computer and use it in GitHub Desktop.
typeof vs instanceof
function isDefined(x) {
return x !== null && x !== undefined;
}
function isObject(x) {
return (typeof x === "function"
|| (typeof x === "object" && x !== null));
}
// 问题:上面的检测比较复杂,是因为 typeof 把函数和对象看成是不同的类型,而且 typeof null 返回 “object”.
// 解决办法:下面的方法也经常用于检测对象值:
function isObject(x) {
return x === Object(x);
}
function getPrimitiveTypeName(x) {
var typeName = typeof x;
switch(typeName) {
case "undefined":
case "boolean":
case "number":
case "string":
return typeName;
case "object":
if (x === null) {
return "null";
}
default:
throw new TypeError("Argument is not a primitive type: " + x);
}
}
// Numbers
console.log(typeof 37) // 'number';
console.log(typeof 3.14) // 'number';
console.log(typeof Math.LN2) // 'number';
console.log(typeof Infinity) // 'number';
console.log(typeof NaN) // 'number'; 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"
console.log(typeof Number(1)) // 'number'; 不要这样使用!
// Strings
console.log(typeof "") // 'string';
console.log(typeof "bla") // 'string';
console.log(typeof (typeof 1)) // 'string'; typeof返回的肯定是一个字符串
console.log(typeof String("abc")) // 'string'; 不要这样使用!
// Booleans
console.log(typeof true) // 'boolean';
console.log(typeof false) // 'boolean';
console.log(typeof Boolean(true)) // 'boolean'; 不要这样使用!
// Undefined
console.log(typeof undefined) // 'undefined';
console.log(typeof blabla) // 'undefined'; 一个未定义的变量,或者一个定义了却未赋初值的变量
// Objects
console.log(typeof {a:1}) // 'object';
console.log(typeof [1, 2, 4]) // 'object';
// 使用Array.isArray或者Object.prototype.toString.call方法
// 可以分辨出一个数组和真实的对象
console.log(typeof new Date()) // 'object';
console.log(typeof new Boolean(true)) // 'object' 令人困惑.不要这样使用
console.log(typeof new Number(1)) // 'object' 令人困惑.不要这样使用
console.log(typeof new String("abc")) // 'object'; 令人困惑.不要这样使用
// Functions
console.log(typeof function(){}) // 'function';
console.log(typeof Math.sin) // 'function';
console.log(Object.prototype.toString.call(1)) // "[object Number]"
console.log(Object.prototype.toString.call('hi')) // "[object String]"
console.log(Object.prototype.toString.call({a:'hi'})) // "[object Object]"
console.log(Object.prototype.toString.call([1,'a'])) // "[object Array]"
console.log(Object.prototype.toString.call(true)) // "[object Boolean]"
console.log(Object.prototype.toString.call(() => {})) // "[object Function]"
console.log(Object.prototype.toString.call(null)) // "[object Null]"
console.log(Object.prototype.toString.call(undefined)) // "[object Undefined]"
console.log(Object.prototype.toString.call(Symbol(1))) // "[object Symbol]"
/**/
function Foo() {}
function Bar() {}
Bar.prototype = new Foo();
console.log(new Bar() instanceof Bar); // true
console.log(new Bar() instanceof Foo); // true
// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例
Bar.prototype = Foo;
console.log(new Bar() instanceof Foo); // false
console.log(new String('foo') instanceof String); // true
console.log(new String('foo') instanceof Object); // true
console.log('foo' instanceof String); // false
console.log('foo' instanceof Object); // false
function C(){} // defining a constructor
function D(){} // defining another constructor
var o = new C();
console.log(o instanceof C); // true, because: Object.getPrototypeOf(o) === C.prototype
console.log(o instanceof D); // false, because D.prototype is nowhere in o's prototype chain
console.log(o instanceof Object); // true, because:
console.log(C.prototype instanceof Object); // true
C.prototype = {};
var o2 = new C();
console.log(o2 instanceof C); // true
console.log(o instanceof C); // false, because C.prototype is nowhere in o's prototype chain anymore
D.prototype = new C(); // use inheritance
var o3 = new D();
console.log(o3 instanceof D); // true
console.log(o3 instanceof C); // true
console.log(Function instanceof Object); //true
console.log(Object instanceof Function); //true
console.log(Function instanceof Function); //true
console.log(Object instanceof Object); // true
console.log(Number instanceof Number); //false
// ①构造器Function的构造器是它自身
console.log(Function.constructor=== Function); //true
// ②构造器Object的构造器是Function(由此可知所有构造器的constructor都指向Function)
console.log(Object.constructor === Function); //true
// ③构造器Function的__proto__是一个特殊的匿名函数function() {}
console.log(Function.__proto__); // ƒ () { [native code] }
// ④这个特殊的匿名函数的__proto__指向Object的prototype原型。
console.log(Function.__proto__.__proto__ === Object.prototype); //true
// ⑤Object的__proto__指向Function的prototype,也就是上面③中所述的特殊匿名函数
console.log(Object.__proto__ === Function.prototype); //true
console.log(Function.prototype === Function.__proto__); //true
/**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment