引言
JavaScript这门语言有些场合的用法还是比较怪异的。这篇文章会尽量将这门语言特有的一些比较特殊的用法收集在一起。就当是平时开发时需要注意的地方吧。
特殊用法收集
1、!!用法
在JavaScript中经常看到判断一个对象是否有某一个属性或者在进行客户端检测的时候会出现!!这个用法。相信大家都看到过var isIE=!!document.all这样的代码把。那为什么需要使用!!呢?
!!作用就在于:如果明确设置了对象中属性的值(非 null/undefined/0/""等值),那么使用!!就可以将该对象中的属性转化为Boolean类型,并且返回true。如果是null/undefined/0/""等值那么使用!!就是返回false。所以!!的使用是将属性或者方法强制转化成Boolean类型。
2、JavaScript中==和===的差异
A、对于string,number等基础类型,==和===是有区别的。
不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等。
B、对于Array,Object等高级类型,==和===是没有区别的
进行“指针地址”比较
C、基础类型与高级类型,==和===是有区别的
对于==,将高级转化为基础类型,进行“值”比较(高级类型典型的如调用toString()后在进行比较)
因为类型不同,===结果为false
3、typeof 操作符和instanceof 操作符
确定一个值是哪一种基本类型可以使用typeof 操作符。确定一个值是哪一种引用类型可以使用instanceof操作符。这些操作符在后续的浏览器特性检测方面很有用。
我在看Mustache.js源代码的时候发现判断一个对象是否是Array有如下的方式。
var objectToString = Object.prototype.toString;
var isArray = Array.isArray || function isArrayPolyfill(object) {
return objectToString.call(object) === '[object Array]';
};
我们知道在判断引用类型的时候我们可以使用instanceof操作符,但是在一些特殊情况下,可能会出现问题。例如:
注意点!
使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!
而通过使用toString.call()方法,我们可以避免一些问题。我们来看ECMA 对Object.prototype.toString的解释。
When the toString method is called, the following steps are taken:
1.If the this value is undefined, return "[object Undefined]".
2.If the this value is null, return "[object Null]".
3.Let O be the result of calling ToObject passing the this value as the argument.
4.Let class be the value of the [[Class]] internal property of O.
5.Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
地址:http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4.2
下面我们举例来看这方面的内容。请看下面的例子:
var oP = Object.prototype,
toString = oP.toString; console.log(toString.call([123]));//[object Array]
console.log(toString.call('123'));//[object String]
console.log(toString.call({a: '123'}));//[object Object]
console.log(toString.call(/123/));//[object RegExp]
console.log(toString.call(123));//[object Number]
console.log(toString.call(undefined));//[object Undefined]
console.log(toString.call(null));//[object Null]
//....