JavaScript Garden2
Types
Equality and Comparisons
JavaScript has two different ways of comparing the values of objects for equality.
The Equality Operator
The equality operator consists of two equal signs: ==
JavaScript features weak typing. This means that the equality operator coerces types in order to compare them.
"" == "0" // false
0 == "" // true
0 == "0" // true
false == "false" // false
false == "0" // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true
The above table shows the results of the type coercion, and it is the main reason why the use of == is widely regarded as bad practice. It introduces hard-to-track-down bugs due to its complicated conversion rules.
Additionally, there is also a performance impact when type coercion is in play; for example, a string has to be converted to a number before it can be compared to another number.
The Strict Equality Operator
The strict equality operator consists of three equal signs: ===.
It works like the normal equality operator, except that strict equality operator does not perform type coercion between its operands.
"" === "0" // false
0 === "" // false
0 === "0" // false
false === "false" // false
false === "0" // false
false === undefined // false
false === null // false
null === undefined // false
" \t\r\n" === 0 // false
The above results are a lot clearer and allow for early breakage of code. This hardens code to a certain degree and also gives performance improvements in case the operands are of different types.
Comparing Objects
While both == and === are called equality operators, they behave differently when at least one of their operands is an Object.
{} === {}; // false
new String('foo') === 'foo'; // false
new Number(10) === 10; // false
var foo = {};
foo === foo; // true
Here, both operators compare for identity and not equality; that is, they will compare for the same instance of the object, much like is in Python and pointer comparison in C.
In Conclusion
It is highly recommended to only use the strict equality operator. In cases where types need to be coerced, it should be done explicitly and not left to the language's complicated coercion rules.
The typeof Operator
The typeof operator (together with instanceof) is probably the biggest design flaw of JavaScript, as it is almost completely broken.
Although instanceof still has limited uses, typeof really has only one practical use case, which does not happen to be checking the type of an object.
Note: While typeof can also be called with a function like syntax, i.e. typeof(obj), this is not a function call. The parentheses behave as normal and the return value will be used as the operand of the typeof operator. There is no typeof function.
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
In the above table, Type refers to the value that the typeof operator returns. As can be clearly seen, this value is anything but consistent.
The Class refers to the value of the internal [[Class]] property of an object.
From the Specification: The value of [[Class]] can be one of the following strings.Arguments, Array, Boolean,Date, Error, Function,JSON, Math, Number,Object, RegExp, String.
In order to retrieve the value of [[Class]], one has to make use of the toString method of Object.prototype.
The Class of an Object
The specification gives exactly one way of accessing the [[Class]] value, with the use of 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
ES5 Note: For convenience the return value of Object.prototype.toString for both null and undefined was changed from Object to Null and Undefined in ECMAScript 5.
In the above example, Object.prototype.toString gets called with the value of this being set to the object whose [[Class]] value should be retrieved.
Testing for Undefined Variables
typeof foo !== 'undefined'
The above will check whether foo was actually declared or not; just referencing it would result in a ReferenceError. This is the only thingtypeof is actually useful for.
In Conclusion
In order to check the type of an object, it is highly recommended to use Object.prototype.toString because this is the only reliable way of doing so. As shown in the above type table, some return values of typeof are not defined in the specification; thus, they can differ between implementations.
Unless checking whether a variable is defined, typeof should be avoided.
The instanceof Operator
The instanceof operator compares the constructors of its two operands. It is only useful when comparing custom made objects. Used on built-in types, it is nearly as useless as the typeof operator.
Comparing Custom Objects
function Foo() {}
function Bar() {}
Bar.prototype = new Foo();
new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true
// This just sets Bar.prototype to the function object Foo,
// but not to an actual instance of Foo
Bar.prototype = Foo;
new Bar() instanceof Foo; // false
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
One important thing to note here is that instanceof does not work on objects that originate from different JavaScript contexts (e.g. different documents in a web browser), since their constructors will not be the exact same object.
In Conclusion
The instanceof operator should only be used when dealing with custom made objects that originate from the same JavaScript context. Just like the typeof operator, every other use of it should be avoided.
Type Casting
JavaScript is a weakly typed language, so it will apply type coercion wherever possible.
// These are true
new Number(10) == 10; // Number.toString() is converted
// back to a number 10 == '10'; // Strings gets converted to Number
10 == '+10 '; // More string madness
10 == '010'; // And more
isNaN(null) == false; // null converts to 0
// which of course is not NaN // These are false
10 == 010;
10 == '-10';
ES5 Note: Number literals that start with a 0 are interpreted as octal (Base 8). Octal support for these has been removed in ECMAScript 5 strict mode.
To avoid the issues above, use of the strict equal operator is highly recommended. Although this avoids a lot of common pitfalls, there are still many further issues that arise from JavaScript's weak typing system.
Constructors of Built-In Types
The constructors of the built in types like Number and String behave differently when being used with the new keyword and without it.
new Number(10) === 10; // False, Object and Number
Number(10) === 10; // True, Number and Number
new Number(10) + 0 === 10; // True, due to implicit conversion
Using a built-in type like Number as a constructor will create a new Number object, but leaving out the new keyword will make the Number function behave like a converter.
In addition, passing literals or non-object values will result in even more type coercion.
The best option is to cast to one of the three possible types explicitly.
Casting to a String
'' + 10 === '10'; // true
By prepending an empty string, a value can easily be cast to a string.
Casting to a Number
+'10' === 10; // true
Using the unary plus operator, it is possible to cast to a number.
Casting to a Boolean
By using the not operator twice, a value can be converted a boolean.
!!'foo'; // true
!!''; // false
!!'0'; // true
!!'1'; // true
!!'-1' // true
!!{}; // true
!!true; // true
JavaScript Garden2的更多相关文章
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收
执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...
- JavaScript进阶之路(一)初学者的开始
一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...
随机推荐
- 刷漆(Codechef October Challenge 2014:Remy paints the fence)
[问题描述] Czy做完了所有的回答出了所有的询问,结果是,他因为脑力消耗过大而变得更虚了:).帮助Czy恢复身材的艰巨任务落到了你的肩上. 正巧,你的花园里有一个由N块排成一条直线的木板组成的栅栏, ...
- 【一起学OpenFOAM】04 OpenFOAM的学习资源
OpenFOAM的学习资料并不多,个人猜测也许是与软件的类型有关系. 对于商用软件来讲,由于要占领市场,软件开发商自然是巴不得会用软件的人越多越好,因为他们卖的是软件,会用的人越多,软件卖得越好.他们 ...
- 《有限元分析基础教程》(曾攀)笔记一-二维杆单元有限元程序(基于Python)
曾攀老师的<有限元分析基础教程>第三章有二维杆单元的推导,并结合一个例题进行了解析解和基于Matlab的程序求解.但是我感觉书中的MATLAB代码有点罗嗦,而且一些实现方法也比较麻烦,比如 ...
- explain 用法详解
explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: expla ...
- easyui源码翻译1.32--LinkButton(按钮)
前言 使用$.fn.linkbutton.defaults重写默认值对象.下载该插件翻译源码 按钮组件使用超链接按钮创建.它使用一个普通的<a>标签进行展示.它可以同时显示一个图标和文本, ...
- webbench的详细使用
webbench是什么?是一款相当给力的网站压力测试工具.(优点自行搜索) 使用webbench需要两大步骤: 1.安装webbench 2.熟悉webbench命令 一.安装webbench 1.下 ...
- C语言关键字 - 铁布衫:const 转载
const 描述:相传C世界中出现了一件极品装备const,它能的出现,让天下所有的刺客,黑客都失业了,在它的保护下,所有的变量都可以完好无损. 作用:const是constant的简写,表示海枯石栏 ...
- android 与usb 设备通信(二)
再次遇到android mUsbManager.getDevicelist() 得不到usb 设备的问题.于是深入去探讨android 与usb 外围设备通信的问题.第一篇文章写的有点乱,本质就是需 ...
- 【HDOJ】1009 FatMouse' Trade
这道题目是一道非常简单的贪心,但是我却修改了1h+.原因就是qsort的comp有bug.其实还是题目中的数据可以为0.除数为0真的要慎重啊.后来改为结构体,加一层循环选取最大值,果然ac啊.wa了几 ...
- $resource
属性/URL映射 AngularJS Resource:与 RESTful API 交互 自定义$resource方法 <!DOCTYPE html> <html ng-app=&q ...