各浏览器对typeof运算符的兑现差别,类型检查和测试

By admin in 4858美高梅 on 2019年3月29日

【范围】typeof再次来到值范围:

【范围】typeof再次回到值范围:

1,IE6/7/第88中学typeof运算符对BOM对象如window,document,location,history等对象的方法重回“object”,标准浏览器都回来“function”。

4.1.4 检查和测试连串

要检查和测试二个变量是还是不是骨干数据类型?第 3 章介绍的 typeof
操作符是最好的工具。说得更有血有肉一
点, typeof 操作符是规定二个变量是字符串、数值、布尔值,依然 undefined
的极品工具。假设变
量的值是一个对象或 null,则 typeof
操作符会像下边例子中所示的那么重临”object”:

var s = "Nicholas";
var b = true;
var i = 22;
var u;
var n = null;
var o = new Object();
alert(typeof s); //string
alert(typeof i); //number
alert(typeof b); //boolean
alert(typeof u); //undefined
alert(typeof n); //object
alert(typeof o); //object
DeterminingTypeExample01.htm

就算在检查和测试宗旨数据类型时 typeof
是万分能干的帮手,但在检查和测试引用类型的值时,这几个操作符的
用处十分小。 经常,
大家并不是想知道有些值是指标,而是想明白它是什么样品种的对象。为此,
ECMAScript
提供了 instanceof 操作符,其语法如下所示:
4858美高梅 ,result = variable instanceof constructor
假使变量是给定引用类型(依据它的原型链来识别;第 6
章将介绍原型链)的实例,那么
instanceof 操作符就会回到 true。请看上面包车型大巴例子:
alert(person instanceof Object); // 变量 person 是 Object 吗?
alert(colors instanceof Array); // 变量 colors 是 Array 吗?
alert(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?
基于规定,全体引用类型的值都以 Object
的实例。因而,在检查和测试三个引用类型值和 Object 构造
函数时, instanceof 操作符始终会回到 true。当然,假若使用 instanceof
操作符检查和测试中央类型的
值,则该操作符始终会回到 false,因为基本类型不是目的。
动用 typeof 操作符检查和测试函数时,该操作符会重返”function”。在 Safari 5 及
事先版本和 Chrome 7 及在此之前版本中采取 typeof
检测正则表达式时,由于专业的原
因,那些操作符也回到”function”。 ECMA-262
规定任何在其间贯彻[[各浏览器对typeof运算符的兑现差别,类型检查和测试。Call]]方法
的靶子都应该在利用 typeof
操作符时再次回到”function”。由于上述浏览器中的正则
表明式也兑现了这些艺术,由此对正则表达式应用 typeof
会重回”function”。在
IE 和 Firefox 中,对正则表达式应用 typeof 会再次来到”object”。

typeof返回值对应
类型 结果
String "string"
Number "number"
Boolean "boolean"
Undefined "undefined"
Object "object"
function函数对象 "function"
Symbol(ES6新增) "symbol"
宿主对象(由JS环境提供) Implementation-dependent
typeof返回值对应
类型 结果
String "string"
Number "number"
Boolean "boolean"
Undefined "undefined"
Object "object"
function函数对象 "function"
Symbol(ES6新增) "symbol"
宿主对象(由JS环境提供) Implementation-dependent
alert(typeof window.alert); // object
alert(typeof document.write); // object
alert(typeof document.getElementById); // object
alert(typeof document.getElementsByTagName); // object
alert(typeof location.reload); // object
alert(typeof history.go); // object

22.1.1 安全的系列车检查测

JavaScript
内置的类型检查和测试机制并非全盘保障。事实上,发生错误否定及错误肯定的景观也不在少
数。比如说 typeof
操作符吧,由于它有一部分无法预言的行为,常常会招致检查和测试数据类型时得到不可信
的结果。 Safari(直至第 4 版)在对正则表明式应用 typeof
操作符时会回来”function”,由此很难确
定有个别值到底是还是不是函数。
再譬如, instanceof 操作符在设有八个全局成效域(像一个页面包涵八个frame)的情形下,也
是难点多多。三个经文的例子(第 5
章也涉嫌过)正是像上边那样将目的标识为数组。
var isArray = value instanceof Array;
上述代码要回去 true, value 必须是2个数组,而且还非得与 Array
构造函数在同个全局效能域
中。(别忘了, Array 是 window 的本性。)借使 value 是在另个 frame
中定义的数组,那么以上代码
就会再次来到 false。
在检查和测试某些对象到底是原生对象依旧开发人员自定义的靶子的时候,也会有标题。出现那一个题材的
案由是浏览器开端原生支持 JSON 对象了。因为众多少人平素在应用 DouglasCrockford 的 JSON 库,而该
库定义了二个大局 JSON 对象。于是开发职员很难显著页面中的 JSON
对象到底是或不是原生的。
杀鸡取蛋上述难题的章程都一模一样。大家明白,在其它值上调用 Object 原生的
toString()方法,都会
归来三个[object
NativeConstructorName]格式的字符串。每一种类在里边都有二个[[Class]]属
性,那个脾性中就钦命了上述字符串中的构造函数名。举个例子吗。
alert(Object.prototype.toString.call(value)); //”[object Array]”
鉴于原生数组的构造函数名与全局成效域非亲非故,由此采取toString()就能担保重临一致的值。利
用那一点,能够成立如下函数:

function isArray(value){
return Object.prototype.toString.call(value) == "[object Array]";
}

一律,也足以依照这一思路来测试有个别值是还是不是原生函数或正则表达式:

function isFunction(value){
return Object.prototype.toString.call(value) == "[object Function]";
}
function isRegExp(value){
return Object.prototype.toString.call(value) == "[object RegExp]";
}

只是要留意,对于在 IE 中以 COM 对象情势完毕的别的函数,
isFunction()都将回到 false(因
为它们并非原生的 JavaScript 函数,请参见第 10 章中更详细的牵线)。
这一技巧也广泛应用于检查和测试原生 JSON 对象。 Object 的
toString()方法不可能检查和测试非原生构造函
数的构造函数名。由此,开发职员定义的别的构造函数都将赶回[object
Object]。有些 JavaScript 库会包
含与下部好像的代码。

 

 

2,Safari/Chrome对正则对象回来function,别的浏览器重回object

var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON)

“[object JSON]”;
在 Web 开发中能够区分原生与非原生 JavaScript
对象10分关键。唯有这么才能适当知道有些对象到
底有何功能。那么些技能能够对其它对象给出正确的结论。
请留意, Object.prototpye.toString()本身也只怕会被修改。本节斟酌的
技术假若 Object.prototpye.toString()是未被改动过的原生版本。

jQuery和lodash都以利用安全的花色检查和测试的,上面是lodash代码:

lodash/.internal/baseGetTag.js

const objectProto = Object.prototype
const hasOwnProperty = objectProto.hasOwnProperty
const toString = objectProto.toString
const symToStringTag = typeof Symbol != 'undefined' ? Symbol.toStringTag : undefined

/**
 * The base implementation of `getTag` without fallbacks for buggy environments.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
function baseGetTag(value) {
  if (value == null) {
    return value === undefined ? '[object Undefined]' : '[object Null]'
  }
  if (!(symToStringTag && symToStringTag in Object(value))) {
    return toString.call(value)
  }
  const isOwn = hasOwnProperty.call(value, symToStringTag)
  const tag = value[symToStringTag]
  let unmasked = false
  try {
    value[symToStringTag] = undefined
    unmasked = true
  } catch (e) {}

  const result = toString.call(value)
  if (unmasked) {
    if (isOwn) {
      value[symToStringTag] = tag
    } else {
      delete value[symToStringTag]
    }
  }
  return result
}

export default baseGetTag

lodash/isFunction.js

import baseGetTag from './.internal/baseGetTag.js'
import isObject from './isObject.js'

/**
 * Checks if `value` is classified as a `Function` object.
 *
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
 * @example
 *
 * isFunction(_)
 * // => true
 *
 * isFunction(/abc/)
 * // => false
 */
function isFunction(value) {
  if (!isObject(value)) {
    return false
  }
  // The use of `Object#toString` avoids issues with the `typeof` operator
  // in Safari 9 which returns 'object' for typed arrays and other constructors.
  const tag = baseGetTag(value)
  return tag == '[object Function]' || tag == '[object AsyncFunction]' ||
    tag == '[object GeneratorFunction]' || tag == '[object Proxy]'
}

export default isFunction

javascript中对变量类型的判断

 

 

var bb = new RegExp('bb');
alert(typeof /aa/);// --> function
alert(typeof bb);// --> function

 

 

3,Safari对NodeList重回function,其余浏览器再次回到object

 

 

var nodes1 = document.body.children
    nodes2 = document.body.childNodes;
alert(typeof nodes1);
alert(typeof nodes2);

 

 

至于typeof运算符,ECMAScript5 11.4.3节有有关申明

 

 

4858美高梅 1

 

 

从上表能够看看

 

 

1,基本项目

 

 

对此Undefined、Null、Boolean、Number、String再次回到字符串”undefined”、”object”、”boolean”、”number”、”string”。
需注意的是对此Null再次回到的不是”null”而是”object”,听大人说是ECMAScript早期版本的笔误而直白三番七次现今。

 

 

2,对象类型

【typeof为何要差别object和function?】

【typeof为啥要区分object和function?】

对象类型又分本地对象(Object)和宿主对象(window),本地对象又分普通对象和函数类型对象。因为JS中等高校函授数是一等国民,即函数自身也是个指标。因而须求区分下。那里的靶子指没有达成call方法的对象。

  1. 答案一:《JavaScript高级程序设计》:从技术角度讲,函数在ECMAScript中是目的,不是一种数据类型。可是,函数也的确有局部非正规的习性,因而通过typeof操作符来区分函数和别的对象是有必不可少的。
  2. 答案二:在骨子里的行使进程中有须求区分Object和Function,所以在typeof那里完毕了
  1. 答案一:《JavaScript高级程序设计》:从技术角度讲,函数在ECMAScript中是目的,不是一种数据类型。可是,函数也的确有一些特有的性质,由此通过typeof操作符来差别函数和别的对象是有须要的。
  2. 答案二:在其实的施用进程中有需要区分Object和Function,所以在typeof那里实现了

平常对象如Object,Array等返回 “object”。

【typeof的不足之处】

【typeof的不足之处】

函数类型对象如new Function格局或function fn(){}、var fn =
function(){}形式赶回“function”。

  1. 不能够分别对象、数组、正则,对它们操作都回到”object”;(正则特殊一点末尾说)
  2. Safar5,Chrome7此前的本子对正则对象回来 ‘function’
  3. 在IE6,7和第88中学,超越1/2的宿主对象是目的,而不是函数;如:typeof alert;
    //object
  4. 而在非ID浏览器或则IE9以上(包含IE9),typeof alert; //function
  1. 不能够分别对象、数组、正则,对它们操作都回到”object”;(正则特殊一点背后说)
  2. Safar5,Chrome7以前的版本对正则对象回来 ‘function’
  3. 在IE6,7和第88中学,大部分的宿主对象是指标,而不是函数;如:typeof alert;
    //object
  4. 而在非ID浏览器或则IE9以上(包括IE9),typeof alert; //function

宿主对象如window,没有完成call方法的目的回来是宿主自定义的,但不可能是”undefined”、”boolean”、”number”、”string”。即宿主的完成无法是JS的宗旨类型的再次回到值,那是言语最宗旨的地点,不然会让人很迷惑。

【记念行为】

【回想行为】

如上正是ECMAScript对typeof描述的漫天。

  1. 基于JS数据类型回忆String/Number/Boolean/Undefined/Object/function再次回到的字符串情势分别为:string/number/boolean/undefined/object/function
  2. 特种记念:
    1. Symbol(ES6新增)=> “symbol”
    2. 无法分别对象、数组、正则,再次来到”object”,正则在Safar5,Chrome7此前的本子中回到”function”
    3. 宿主对象,IE6/7/8赶回”object”,其余浏览器再次来到”function”
    4. 杰出中的特殊
      typeof 1/0; //NaN(这个NaN不是字符串类型,是数值类型)
      typeof typeof 1/0; //NaN(这个NaN不是字符串类型,是数值类型)
      typeof(1/0); //"number"
      typeof typeof(1/0); //"string"
      typeof(typeof 1/0); //"number"
      
  1. 遵照JS数据类型回忆String/Number/Boolean/Undefined/Object/function重回的字符串格局分别为:string/number/boolean/undefined/object/function
  2. 破例纪念:
    1. Symbol(ES6新增)=> “symbol”
    2. 无法分别对象、数组、正则,再次回到”object”,正则在Safar5,Chrome7从前的本子中回到”function”
    3. 宿主对象,IE6/7/5回去”object”,别的浏览器再次来到”function”
    4. 奇异中的特殊
      typeof 1/0; //NaN(这个NaN不是字符串类型,是数值类型)
      typeof typeof 1/0; //NaN(这个NaN不是字符串类型,是数值类型)
      typeof(1/0); //"number"
      typeof typeof(1/0); //"string"
      typeof(typeof 1/0); //"number"
      

对此上述列举的八个出入的第叁条:Safari/Chrome对正则对象回来function,别的浏览器重临object,那足以认为是Safari/Chrome的Bug,即没有按标准ECMAScript5完结。正则表明式是非宿主普通对象(见ECMAScript5
15.10 RegExp (Regular Expression) Objects),而又从未兑现call方法。如

【标题和答案】

【标题和答案】

var reg = /aa/;
alert(reg.call); // undefined
alert(reg.test); // native code
// 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 declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === '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';

//NaN
typeof 1/0 === 'NaN';
// 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 declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === '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';

//NaN
typeof 1/0 === 'NaN';

为此对于typeof运算应该回到“object”而不是“function”。

 

 

对此第贰条和第1条,宿主对象,除了无法回去”undefined”、”boolean”、”number”、”string”外,具体再次来到吗由浏览器自行完毕。我们看一个示范window.alert

alert(alert.call); // IE6/7/8中undefined,IE9/Firefox/Safari/Chrome/Opera中native code

能够看出IE6/7/第88中学alert是尚未call方法的,因而typeof
window.alert,IE6/7/8中回到“object”也从没违反规范,只是让开发者觉得很迷惑,因为从学JS的率后天初叶就认为alert是window对象的一个措施/函数。

正因为ECMAScript对于宿主对象没有严酷的定义typeof,从而在IE中动用typeof运算符重回”date”、”unknow”之类的就数见不鲜了。

xhr = new ActiveXObject("Msxml2.XMLHTTP");
alert(typeof xhr.abort); // IE6/7/8/9中都返回 unknow

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有