详解JavaScript中typeof与instanceof用法


Posted in Javascript onOctober 24, 2018

今天写JS代码,遇到动态生成多个名称相同的input复选按钮

需要判断其是否是数组,用到了if (typeof(document.MapCheckMgr.checkid)!="undefined")

以前用得少,就顺便查了一下关于typeof的那些事

 typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:

number,boolean,string,function(函数),object(NULL,数组,对象),undefined。

如:

alert(typeof (123));//typeof(123)返回"number" 
alert(typeof ("123"));//typeof("123")返回"string"

我们可以使用typeof来获取一个变量是否存在,如if(typeof a!="undefined"){},而不要去使用if(a)因为如果a不存在(未声明)则会出错,

正因为typeof遇到null,数组,对象时都会返回object类型,所以当我们要判断一个对象是否是数组时

或者判断某个变量是否是某个对象的实例则要选择使用另一个关键语法instanceof

instanceof用于判断一个变量是否某个对象的实例,如var a=new Array();alert(a instanceof Array);会返回true,

同时alert(a instanceof Object)也会返回true;这是因为Array是object的子类。

再如:function test(){};var a=new test();alert(a instanceof test)会返回true。

<script>
  var str = new String();
  function show(str1){
  if(str1 instanceof String){
    alert('1');
  }else{
    alert('0');
  }
  }
  show(str);
  str = "abccddd";
  if(typeof str=='string'){alert(str);}
  else{alert('0');}
 </script>

  关于typeof

typeof一元运算符,用来返回操作数类型的字符串。

typeof几乎不可能得到它们想要的结果。typeof只有一个实际应用场景,就是用来检测一个对象是否已经定义或者是否已经赋值。而这个应用却不是来检查对象的类型。

Value Class Type
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object

上面表格中,Type 一列表示 typeof 操作符的运算结果。可以看到,这个值在大多数情况下都返回 "object"。

Class 一列表示对象的内部属性 [[Class]] 的值。

JavaScript 标准文档中定义: [[Class]] 的值只可能是下面字符串中的一个: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String.

为了获取对象的 [[Class]],我们需要使用定义在 Object.prototype 上的方法 toString。

对象的类定义

JavaScript 标准文档只给出了一种获取 [[Class]] 值的方法,那就是使用 Object.prototype.toString。

function is(type, obj) {
  var clas = Object.prototype.toString.call(obj).slice(8, -1);
  return obj !== undefined && obj !== null && clas === type;
}
is('String', 'test'); // true
is('String', new String('test')); // true

上面例子中,Object.prototype.toString 方法被调用,this 被设置为了需要获取 [[Class]] 值的对象。

注:Object.prototype.toString 返回一种标准格式字符串,所以上例可以通过 slice 截取指定位置的字符串,如下所示:

Object.prototype.toString.call([])  // "[object Array]"
Object.prototype.toString.call({})  // "[object Object]"
Object.prototype.toString.call(2)  // "[object Number]"

注:这种变化可以从 IE8 和 Firefox 4 中看出区别,如下所示:

// IE8
Object.prototype.toString.call(null)  // "[object Object]"
Object.prototype.toString.call(undefined)  // "[object Object]"

// Firefox 4
Object.prototype.toString.call(null)  // "[object Null]"
Object.prototype.toString.call(undefined)  // "[object Undefined]"

测试为定义变量

typeof foo !== 'undefined'

上面代码会检测 foo 是否已经定义;如果没有定义而直接使用会导致 ReferenceError 的异常。 这是 typeof 唯一有用的地方。

结论

为了检测一个对象的类型,强烈推荐使用 Object.prototype.toString 方法; 因为这是唯一一个可依赖的方式。正如上面表格所示,typeof 的一些返回值在标准文档中并未定义, 因此不同的引擎实现可能不同。

除非为了检测一个变量是否已经定义,我们应尽量避免使用 typeof 操作符。

x typeof x
undefined "undefined"
true 或false "boolean"
任意数字或者NaN "number"
任意字符串 "string"
函数对象(在ECMA-262术语中,指的是实现了[[Call]] 的对象) "function"
任意内置对象(非函数) "object"
数组 "obeject"
null "object"
宿主对象(JS引擎内置对象,而不是DOM或者其他提供的) 由编译器各自实现的字符串,但不是"undefined","number","boolean","number","string"。
正则表达式 各浏览器表现不一

如果想将null和对象区分开,则必须针对特殊值显式检测。如:my_value===null。对于宿主对象来说,typeof有可能并不返回‘object',而返回字符串。但实际上客户端js中的大多数宿主对象都是‘object'类型。对于所有内置可执行对象进行typeof运算都将返回“function”。

// 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'; // 不要这样使用!
// Undefined
typeof undefined === 'undefined';
typeof blabla === 'undefined'; // 一个未定义的变量,或者一个定义了却未赋初值的变量
// Objects
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object'; 
// 使用Array.isArray或者Object.prototype.toString.call方法
//可以分辨出一个数组和真实的对象
typeof new Date() === 'object';
typeof new Boolean(true) === 'object' // 令人困惑.不要这样使用
typeof new Number(1) === 'object' // 令人困惑.不要这样使用
typeof new String("abc") === 'object'; // 令人困惑.不要这样使用
// Functions
typeof function(){} === 'function';
typeof Math.sin === 'function';

关于instanceof

instanceof 左操作数是一个类,右操作数是标识对象的类。如果左侧的对象是右侧类的实例,则返回true.而js中对象的类是通过初始化它们的构造函数来定义的。即instanceof的右操作数应当是一个函数。所有的对象都是object的实例。如果左操作数不是对象,则返回false,如果右操作数不是函数,则抛出typeError。

instanceof 运算符是用来测试一个对象是否在其原型链原型构造函数的属性。其语法是object instanceof constructor

instanceof 操作符用来比较两个操作数的构造函数。只有在比较自定义的对象时才有意义。 如果用来比较内置类型,将会和 typeof 操作符 一样用处不大。

比较自定义对象

function Foo() {}
function Bar() {}
Bar.prototype = new Foo();
new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true
// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例
Bar.prototype = Foo;
new Bar() instanceof Foo; // false

instanceof 比较内置类型

new String('foo') instanceof String; // true
new String('foo') instanceof Object; // true
'foo' instanceof String; // false
'foo' instanceof Object; // false

有一点需要注意,instanceof 用来比较属于不同 JavaScript 上下文的对象(比如,浏览器中不同的文档结构)时将会出错, 因为它们的构造函数不会是同一个对象。

结论:instanceof 操作符应该仅仅用来比较来自同一个 JavaScript 上下文的自定义对象。 正如 typeof 操作符一样,任何其它的用法都应该是避免的。

function C(){} // defining a constructor
function D(){} // defining another constructor
var o = new C();
o instanceof C; // true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false, because D.prototype is nowhere in o's prototype chain
o instanceof Object; // true, because:
C.prototype instanceof Object // true
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
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();
o3 instanceof D; // true
o3 instanceof C; // true
var myString = new String();
var myDate = new Date();
myString instanceof String; // returns true
myString instanceof Object; // returns true
myString instanceof Date;  // returns false
myDate instanceof Date;   // returns true
myDate instanceof Object;  // returns true
myDate instanceof String;  // returns false
function Car(make, model, year) {
 this.make = make;
 this.model = model;
 this.year = year;
}
var mycar = new Car("Honda", "Accord", 1998);
var a = mycar instanceof Car;  // returns true
var b = mycar instanceof Object; // returns true

总结

以上所述是小编给大家介绍的JavaScript中typeof与instanceof用法 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
cnblogs 代码高亮显示后的代码复制问题解决实现代码
Dec 14 Javascript
返回页面顶部top按钮通过锚点实现(自写)
Aug 30 Javascript
Chrome扩展页面动态绑定JS事件提示错误
Feb 11 Javascript
JS+CSS实现可拖动的弹出提示框
Feb 16 Javascript
js判断鼠标位置是否在某个div中的方法
Feb 26 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
Oct 26 Javascript
JS面向对象的程序设计相关知识小结
May 26 Javascript
Vue 事件处理操作实例详解
Mar 05 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
May 16 Javascript
微信小程序实现文件、图片上传功能
Aug 18 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
Jul 30 Javascript
vue keep-alive的简单总结
Jan 25 Vue.js
使用electron实现百度网盘悬浮窗口功能的示例代码
Oct 24 #Javascript
JavaScript根据json生成html表格的示例代码
Oct 24 #Javascript
vue项目引入Iconfont图标库的教程图解
Oct 24 #Javascript
vue中的router-view组件的使用教程
Oct 23 #Javascript
jQuery pagination分页示例详解
Oct 23 #jQuery
jquery.pagination.js分页使用教程
Oct 23 #jQuery
vue项目使用微信公众号支付总结及遇到的坑
Oct 23 #Javascript
You might like
B2K与车机的中波PK
2021/03/02 无线电
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
Yii框架实现对数据库的CURD操作示例
2019/09/03 PHP
js清理Word格式示例代码
2014/02/13 Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
2015/07/27 Javascript
全面解析Bootstrap表单使用方法(表单样式)
2015/11/24 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
2016/02/21 Javascript
TypeScript Type Innference(类型判断)
2016/03/10 Javascript
浅析JS操作DOM的一些常用方法
2016/05/13 Javascript
Bootstrap源码解读标签、徽章、缩略图和警示框(8)
2016/12/26 Javascript
jQuery Chosen通用初始化
2017/03/07 Javascript
详解react-router 4.0 下服务器如何配合BrowserRouter
2017/12/29 Javascript
Vuex中mutations与actions的区别详解
2018/03/01 Javascript
Vue 重置组件到初始状态的方法示例
2018/10/10 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
JS尾递归的实现方法及代码优化技巧
2019/01/19 Javascript
layui下拉框获取下拉值(select)的例子
2019/09/10 Javascript
解决Vue动态加载本地图片问题
2019/10/09 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
2020/08/17 Javascript
[54:33]2018DOTA2亚洲邀请赛小组赛 A组加赛 Liquid vs Optic
2018/04/03 DOTA
神经网络相关之基础概念的讲解
2018/12/29 Python
python 中的列表生成式、生成器表达式、模块导入
2019/06/19 Python
python实现电子词典
2020/03/03 Python
Python SQLAlchemy库的使用方法
2020/10/13 Python
使用python将微信image下.dat文件解密为.png的方法
2020/11/30 Python
详解python中的三种命令行模块(sys.argv,argparse,click)
2020/12/15 Python
详解H5 活动页之移动端 REM 布局适配方法
2017/12/07 HTML / CSS
就业协议书范本
2014/04/11 职场文书
移风易俗倡议书
2014/04/15 职场文书
难忘的一天教学反思
2014/04/30 职场文书
2015年幼儿园德育工作总结
2015/05/25 职场文书
nginx限制并发连接请求数的方法
2021/04/01 Servers
Golang 空map和未初始化map的注意事项说明
2021/04/29 Golang
python 下划线的多种应用场景总结
2021/05/12 Python
修改并编译golang源码的操作步骤
2021/07/25 Golang
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫