GVKun编程网logo

JavaScript中 奇怪的typeof解析 (Null, Array)(javascript typeerror)

12

想了解JavaScript中奇怪的typeof解析的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于Null,Array的相关问题,此外,我们还将为您介绍关于Array,ArrayConstr

想了解JavaScript中 奇怪的typeof解析 的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于Null, Array的相关问题,此外,我们还将为您介绍关于Array, Array Constructor, for in loop, typeof, instanceOf_javascript技巧、JavaScript "new Array(n)" 和 "Array.prototype.map" 怪异、JavaScript typeof, null, 和 undefined的相关知识、javascript typeof的用法与typeof运算符介绍[详细]_javascript技巧的新知识。

本文目录一览:

JavaScript中 奇怪的typeof解析 (Null, Array)(javascript typeerror)

JavaScript中 奇怪的typeof解析 (Null, Array)(javascript typeerror)

在JavaScript中,我们常常用到typeof 来判断一个元素的类型,但是在实际开发中我们会发现一个很难受的问题。

 

      Null,Array      (孤立他俩)

 

 在 typeof Null 和  typeof Array中 居然返回的是 Object类型,。。。。。。。

 

   纳尼!!!上去就给他俩一个反抽!!难道是哪里写错了么????

 

原来是因为,javascript在当初设计的时候出现的BUG (突然感觉自己很牛掰)。

 

在 ES6制定 中曾有关于修复此 bug 的提议,提议中称应该让 typeof Null === ''null'', 但是最后因为考虑到历史积累代码牵扯范围太广,责任重大取消这一个更改,也就是说这不在是一个

BUG了,而是龟ding。而对于Array,typeof本着万物皆对象的原则,返回的结果就是 Object了  (原因其实很复杂,设计到Javascript的底层二进制解析,感兴趣可以在网上查下,资料很多

 

那么问题来了,在我们实际开发中,需要准确的区别 Number,Array,Object,String,Null,undefined甚至是funtion的时候怎么办??????????

 

废话说了这么多,进入正题 (代码奉上)

  

//  
		function typeOf (obj) {
		    return toString.call(obj).slice(8, -1)
		};

		//
		let fun = function () {
			console.log (123);
		}
		//
		let objs = typeOf ({key: ''123'', val: ''345''});
		let num =  typeOf (123);
		let str =  typeOf (''我是个字符串'');
		let arr =  typeOf ( [''11'', ''22'', ''33'']);
		let nulls = typeOf (null);
		let un = typeOf (undefined);
		let funs = typeOf (fun);

		console.log (objs, num, str, arr, nulls, un, funs);

 

  

 

 

结果:

  

 

  本人:小白一枚,第一次写博客,有什么写错的地方,请各位大神指点出来,必定虚心学习

 

Array, Array Constructor, for in loop, typeof, instanceOf_javascript技巧

Array, Array Constructor, for in loop, typeof, instanceOf_javascript技巧

注意: JavaScript 中数组不是 关联数组。 JavaScript 中只有对象 来管理键值的对应关系。但是关联数组是保持顺序的,而对象不是。

由于 for in 循环会枚举原型链上的所有属性,唯一过滤这些属性的方式是使用 `hasOwnProperty` 函数,因此会比普通的 for 循环慢上好多倍。

遍历(Iteration)
为了达到遍历数组的最佳性能,推荐使用经典的 for 循环。

复制代码 代码如下:

var list = [1, 2, 3, 4, 5, ...... 100000000];
for(var i = 0, l = list.length; i console.log(list[i]);
}

上面代码有一个处理,就是通过 l = list.length 来缓存数组的长度。

虽然 length 是数组的一个属性,但是在每次循环中访问它还是有性能开销。 可能最新的 JavaScript 引擎在这点上做了优化,但是我们没法保证自己的代码是否运行在这些最近的引擎之上。

实际上,不使用缓存数组长度的方式比缓存版本要慢很多。

`length` 属性(The `length` property)
length 属性的 getter 方式会简单的返回数组的长度,而 setter 方式会截断数组。
复制代码 代码如下:

var foo = [1, 2, 3, 4, 5, 6];
foo.length = 3;
foo; // [1, 2, 3]

foo.length = 6;
foo; // [1, 2, 3]

译者注:在 Firebug 中查看此时 foo 的值是: [1, 2, 3, undefined, undefined, undefined] 但是这个结果并不准确,如果你在 Chrome 的控制台查看 foo 的结果,你会发现是这样的: [1, 2, 3] 因为在 JavaScript 中 undefined 是一个变量,注意是变量不是关键字,因此上面两个结果的意义是完全不相同的。

// 译者注:为了验证,我们来执行下面代码,看序号 5 是否存在于 foo 中。
5 in foo; // 不管在 Firebug 或者 Chrome 都返回 false
foo[5] = undefined;
5 in foo; // 不管在 Firebug 或者 Chrome 都返回 true
为 length 设置一个更小的值会截断数组,但是增大 length 属性值不会对数组产生影响。

结论(In conclusion)
为了更好的性能,推荐使用普通的 for 循环并缓存数组的 length 属性。使用 for in 遍历数组被认为是不好的代码习惯并倾向于产生错误和导致性能问题。

Array 构造函数
由于 Array 的构造函数在如何处理参数时有点模棱两可,因此总是推荐使用数组的字面语法 - [] - 来创建数组。

[1, 2, 3]; // 结果: [1, 2, 3]
new Array(1, 2, 3); // 结果: [1, 2, 3]

[3]; // 结果: [3]
new Array(3); // 结果: []
new Array(''3'') // 结果: [''3'']
译者注:这里的模棱两可指的是数组的两种构造函数语法 var arr1 = new Array(arrayLength); var arr2 = new Array(element0, element1, ..., elementN);

// 译者注:因此下面的代码将会使人很迷惑
new Array(3, 4, 5); // 结果: [3, 4, 5]
new Array(3) // 结果: [],此数组长度为 3
由于只有一个参数传递到构造函数中(译者注:指的是 new Array(3); 这种调用方式),并且这个参数是数字,构造函数会返回一个 length 属性被设置为此参数的空数组。需要特别注意的是,此时只有 length 属性被设置,真正的数组并没有生成。译者注:在 Firebug 中,你会看到 [undefined, undefined, undefined],这其实是不对的。在上一节有详细的分析。

var arr = new Array(3);
arr[1]; // undefined
1 in arr; // false, 数组还没有生成
这种优先于设置数组长度属性的做法只在少数几种情况下有用,比如需要循环字符串,可以避免 for 循环的麻烦。

new Array(count + 1).join(stringToRepeat);
// 译者注:new Array(3).join(''#'') 将会返回 "##"
结论(In conclusion)
应该尽量避免使用数组构造函数创建新数组。推荐使用数组的字面语法。它们更加短小和简洁,因此增加了代码的可读性。

for in 循环
和 in 操作符一样,for in 循环同样在查找对象属性时遍历原型链上的所有属性。

注意: for in 循环不会遍历那些 enumerable 设置为 false 的属性;比如数组的 length 属性。
复制代码 代码如下:

// 修改 Object.prototype
Object.prototype.bar = 1;

var foo = {moo: 2};
for(var i in foo) {
console.log(i); // 输出两个属性:bar 和 moo
}

由于不可能改变 for in 自身的行为,因此有必要过滤出那些不希望出现在循环体中的属性,这可以通过 Object.prototype 原型上的 `hasOwnProperty` 函数来完成。

注意: 由于 for in 总是要遍历整个原型链,因此如果一个对象的继承层次太深的话会影响性能。

使用 `hasOwnProperty` 过滤(Using `hasOwnProperty` for filtering)
复制代码 代码如下:

// foo 变量是上例中的
for(var i in foo) {
if (foo.hasOwnProperty(i)) {
console.log(i);
}
}

这个版本的代码是唯一正确的写法。由于我们使用了 hasOwnProperty,所以这次只输出 moo。如果不使用 hasOwnProperty,则这段代码在原生对象原型(比如 Object.prototype)被扩展时可能会出错。

一个广泛使用的类库 Prototype 就扩展了原生的 JavaScript 对象。因此,但这个类库被包含在页面中时,不使用 hasOwnProperty 过滤的 for in 循环难免会出问题。

最佳实践(Best practices)
推荐总是使用 hasOwnProperty。不要对代码运行的环境做任何假设,不要假设原生对象是否已经被扩展了。

typeof 操作符
typeof 操作符(和 `instanceof` 一起)或许是 JavaScript 中最大的设计缺陷,因为几乎不可能从它们那里得到想要的结果。

尽管 instanceof 还有一些极少数的应用场景,typeof 只有一个实际的应用(译者注:这个实际应用是用来检测一个对象是否已经定义或者是否已经赋值),而这个应用却不是用来检查对象的类型。

注意: 由于 typeof 也可以像函数的语法被调用,比如 typeof(obj),但这并是一个函数调用。那两个小括号只是用来计算一个表达式的值,这个返回值会作为 typeof 操作符的一个操作数。实际上不存在名为 typeof 的函数。

JavaScript 类型表格(The JavaScript type table)
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。

对象的类定义(The Class of an object)
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]"

ES5 提示: 在 ECMAScript 5 中,为了方便,对 null 和 undefined 调用 Object.prototype.toString 方法,其返回值由 Object 变成了 Null 和 Undefined。

译者注:这种变化可以从 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]"
测试为定义变量(Testing for undefined variables)
typeof foo !== ''undefined''

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

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

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

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

比较自定义对象(Comparing custom objects)
复制代码 代码如下:

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` 比较内置类型(Using `instanceof` with native types)
new String(''foo'') instanceof String; // true
new String(''foo'') instanceof Object; // true

''foo'' instanceof String; // false
''foo'' instanceof Object; // false

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

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

JavaScript

JavaScript "new Array(n)" 和 "Array.prototype.map" 怪异

我在 Firefox-3.5.7/Firebug-1.5.3 和 Firefox-3.6.16/Firebug-1.6.2 中观察到了这一点

当我启动 Firebug 时:

var x = new Array(3)

console.log(x)

// [undefined,undefined,undefined]



var y = [undefined,undefined]

console.log(y)

// [undefined,undefined]



console.log( x.constructor == y.constructor) // true



console.log(

  x.map(function() { return 0; })

)

// [undefined,undefined]



console.log(

  y.map(function() { return 0; })

)

// [0,0]

这里发生了什么?这是一个错误,还是我误解了如何使用new Array(3)

JavaScript typeof, null, 和 undefined的相关知识

JavaScript typeof, null, 和 undefined的相关知识

JavaScript typeof, null, 和 undefined这些操作符在js中起到很重要的作用,让我们来详细的讲解下吧。

typeof 操作符

你可以使用 typeof 操作符来检测变量的数据类型。

实例

typeof "John"                // 返回 string 
typeof 3.14                  // 返回 number
typeof false                 // 返回 boolean
typeof [1,2,3,4]             // 返回 object
typeof {name:'John', age:34} // 返回 object
登录后复制

在JavaScript中,数组是一种特殊的对象类型。 因此 typeof [1,2,3,4] 返回 object。

立即学习“Java免费学习笔记(深入)”;

null

在 JavaScript 中 null 表示 "什么都没有"。

null是一个只有一个值的特殊类型。表示一个空对象引用。

用 typeof 检测 null 返回是object。

你可以设置为 null 来清空对象:

实例

var person = null;           // 值为 null(空), 但类型为对象
登录后复制

你可以设置为 undefined 来清空对象:

实例

var person = undefined;     // 值为 undefined, 类型为 undefined
登录后复制

undefined

在 JavaScript 中, undefined 是一个没有设置值的变量。

typeof 一个没有值的变量会返回 undefined。

实例

var person;                  // 值为 undefined(空), 类型是undefined
登录后复制

任何变量都可以通过设置值为 undefined 来清空。 类型为 undefined.

实例

person = undefined;          // 值为 undefined, 类型是undefined
登录后复制

undefined 和 null 的区别

实例

null 和 undefined 的值相等,但类型不等:

typeof undefined             // undefined
typeof null                  // object
null === undefined           // false
null == undefined            // true
登录后复制

本文详细的讲解了JavaScript typeof, null, 和 undefined的相关知识,更多的学习资料清关注php中文网即可观看。

相关推荐:

JavaScript Date(日期) 相关知识与用法

JavaScript RegExp 对象的使用介绍

关于JavaScript Array(数组) 对象的使用方法

以上就是JavaScript typeof, null, 和 undefined的相关知识的详细内容,更多请关注php中文网其它相关文章!

javascript typeof的用法与typeof运算符介绍[详细]_javascript技巧

javascript typeof的用法与typeof运算符介绍[详细]_javascript技巧

下面是对于typeof运算符的详细介绍跟typeof的一些用法,分析,学习typeof的朋友,看完了,这篇应该能有所收获。

经常会在js里用到数组,比如 多个名字相同的input, 若是动态生成的, 提交时就需要判断其是否是数组.
if(document.mylist.length != "undefined" ) {} 这个用法有误.
正确的是 if( typeof(document.mylist.length) != "undefined" ) {}
或 if( !isNaN(document.mylist.length) ) {}
typeof的运算数未定义,返回的就是 "undefined".
运算数为数字 typeof(x) = "number"
字符串 typeof(x) = "string"
布尔值 typeof(x) = "boolean"
对象,数组和null typeof(x) = "object"
函数 typeof(x) = "function"
typeof 运算符返回一个用来表示表达式的数据类型的字符串。
可能的字符串有:"number"、"string"、"boolean"、"object"、"function" 和 "undefined"。
如:
alert(typeof (123));//typeof(123)返回"number"
alert(typeof ("123"));//typeof("123")返回"string"
typeof 运算符
返回一个用来表示表达式的数据类型的字符串。
typeof[()expression[]] ;
expression 参数是需要查找类型信息的任意表达式。
说明
typeof 运算符把类型信息当作字符串返回。typeof 返回值有六种可能: "number," "string," "boolean," "object," "function," 和 "undefined."
typeof 语法中的圆括号是可选项。

typeof运算符介绍:
typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。
它返回值是一个字符串,该字符串说明运算数的类型。
你知道下面typeof运算的结果吗?
typeof(1);
typeof(NaN);
typeof(Number.MIN_VALUE);
typeof(Infinity);
typeof("123");
typeof(true);
typeof(window);
typeof(document);
typeof(null);
typeof(eval);
typeof(Date);
typeof(sss);
typeof(undefined);
看看你会几个?

如果看了以后,不是很明白的话,请看下面(明白的人就不用往下看了):
typeof是一个一元运算符,它返回的结果始终是一个字符串,对不同的操作数,它返回不同的结果。
具体的规则如下:
一、对于数字类型的操作数而言, typeof 返回的值是 number。比如说:typeof(1),返回的值就是number。
上面是举的常规数字,对于非常规的数字类型而言,其结果返回的也是number。比如typeof(NaN),NaN在
JavaScript中代表的是特殊非数字值,虽然它本身是一个数字类型。
在JavaScript中,特殊的数字类型还有几种:
Infinity 表示无穷大特殊值
NaN            特殊的非数字值
Number.MAX_VALUE     可表示的最大数字
Number.MIN_VALUE     可表示的最小数字(与零最接近)
Number.NaN        特殊的非数字值
Number.POSITIVE_INFINITY 表示正无穷大的特殊值
Number.NEGATIVE_INFINITY 表示负无穷大的特殊值
以上特殊类型,在用typeof进行运算进,其结果都将是number。
二、对于字符串类型, typeof 返回的值是 string。比如typeof("123")返回的值是string。
三、对于布尔类型, typeof 返回的值是 boolean 。比如typeof(true)返回的值是boolean。
四、对于对象、数组、null 返回的值是 object 。比如typeof(window),typeof(document),typeof(null)返回的值都是object。
五、对于函数类型,返回的值是 function。比如:typeof(eval),typeof(Date)返回的值都是function。
六、如果运算数是没有定义的(比如说不存在的变量、函数或者undefined),将返回undefined。比如:typeof(sss)、typeof(undefined)都返回undefined。

<script> <br/>document.write ("typeof(1): "+typeof(1)+"<br>"); <br/>document.write ("typeof(NaN): "+typeof(NaN)+"<br>"); <br/>document.write ("typeof(Number.MIN_VALUE): "+typeof(Number.MIN_VALUE)+"<br>") <br/>document.write ("typeof(Infinity): "+typeof(Infinity)+"<br>") <br/>document.write ("typeof(\"123\"): "+typeof("123")+"<br>") <br/>document.write ("typeof(true): "+typeof(true)+"<br>") <br/>document.write ("typeof(window): "+typeof(window)+"<br>") <br/>document.write ("typeof(document): "+typeof(document)+"<br>") <br/>document.write ("typeof(null): "+typeof(null)+"<br>") <br/>document.write ("typeof(eval): "+typeof(eval)+"<br>") <br/>document.write ("typeof(Date): "+typeof(Date)+"<br>") <br/>document.write ("typeof(sss): "+typeof(sss)+"<br>") <br/>document.write ("typeof(undefined): "+typeof(undefined)+"<br>") <br/></script>

我们今天的关于JavaScript中 奇怪的typeof解析 Null, Array的分享已经告一段落,感谢您的关注,如果您想了解更多关于Array, Array Constructor, for in loop, typeof, instanceOf_javascript技巧、JavaScript "new Array(n)" 和 "Array.prototype.map" 怪异、JavaScript typeof, null, 和 undefined的相关知识、javascript typeof的用法与typeof运算符介绍[详细]_javascript技巧的相关信息,请在本站查询。

本文标签: