一、typeof
含义
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
语法用法
typeof [attr]
attr: 一个表示对象或原始值的表达式,其类型将被返回。
// 数值
typeof 37 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number';
// 字符串
typeof '' === 'string';
typeof 'bla' === 'string';
// 布尔值
typeof true === 'boolean';
typeof false === 'boolean';
// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
// Undefined
typeof undefined === 'undefined';
// 对象
typeof {a: 1} === 'object';
// 区分数组和普通对象
typeof [1, 2, 4] === 'object';
typeof new Date() === 'object';
typeof /regex/ === 'object';
// 函数
typeof function() {} === 'function';
typeof class C {} === 'function'
typeof Math.sin === 'function';
// JavaScript 诞生以来便如此
/*在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 *0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。
*/
typeof null === 'object';
局限性
从上述代码示例中可看到,对数组,对象,正则和null使用typeof都会返回’object‘,可见typeof无法区分数组,对象和正则。
二、instanceof
含义
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
语法用法
object instanceof constructor
object: 某个实例对象
constructor: 某个构造函数
/* 摘自MDN */
// 定义构造函数
function C(){}
function D(){}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype 不在 o 的原型链上
o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object // true,同上
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.
D.prototype = new C(); // 继承 D extends C
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上
instanceof也可以检测数据类型
var a = [];
a instanceof Array; // true 说明a是一个数组
局限性
可以判断对象的类型,但无法判断基本类型数据。
三、in
含义
in 运算符用来检测一个属性是否属于某个对象
语法用法
[attr] in [obj]
attrt: 某个属性名称,类型为字符串
obj: 某个类的实例对象
function Fn(name, age) {
this.name = name;
this.age = age;
this.getAttr() {
}
}
var f1 = new Fn('name', 10);
'name' in f1; //true,name是f1的一个属性
'getAttr' in f1; //true,getAttr是f1的一个属性0
局限性
in 运算符无法区分自身属性和继承属性
function C(){
this.c1 = 100;
}
function D(){
this.d1 = 200;
}
D.prototype = new C(); // 继承 D extends C
var dd = new D();
console.log('c1' in dd); // true
console.log('d1' in dd);// true
/* c1 和 d1 都属于dd实例对象的属性,所以都返回true,但是d1是继承自类D的属性*/
四、hasOwnProperty()
含义
所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
语法用法
obj.hasOwnProperty(prop)
obj: 实例对象
prop: 要检测的属性的 String 字符串形式表示的名称,或者 Symbol。
即使属性的值是 null 或 undefined,只要属性存在,hasOwnProperty 依旧会返回 true。
function C(){
this.c1 = 100;
}
function D(){
this.d1 = 200;
this.d2 = null;
this.d3 = undefined;
}
D.prototype = new C(); // 继承 D extends C
var dd = new D();
// 下面的例子演示了 hasOwnProperty 方法对待自身属性和继承属性的区别
dd.hasOwnProperty('d1'); //true
dd.hasOwnProperty('d2'); //true
dd.hasOwnProperty('d3'); //true
dd.hasOwnProperty('c1'); //false
扩展
判断一个属性是否是实例的继承属性
//判断是否是继承属性,返回布尔类型值
function hasOwnExtendProterty(prop) {
return prop in this && !(this.hasOwnProperty(prop));
}
function C(){
this.c1 = 100;
}
function D(){
this.d1 = 200;
this.d2 = null;
this.d3 = undefined;
}
C.prototype.hasOwnExtendProterty = hasOwnExtendProterty;
D.prototype = new C(); // 继承 D extends C
var dd = new D();
// 下面的例子演示了 hasOwnExtendProterty方法
dd.hasOwnExtendProterty('d1'); //false
dd.hasOwnExtendProterty('d2'); //false
dd.hasOwnExtendProterty('d3'); //false
dd.hasOwnExtendProterty('c1'); //true
四、isPrototypeOf()
含义
isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
语法用法
prototypeObj.isPrototypeOf(obj)
prototypeObj:被检测对象
obj: 上层类的实例对象
// 摘自MDN
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);
var baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true