close
当前位置: 物联网在线 > 技术文库 > ios >

JavaScript 新手的踩坑日记

JavaScript 新手的踩坑日记

引语

在1995年5月,Eich 大神在10天内就写出了第一个脚本语言的版本,JavaScript 的第一个代号是 Mocha,Marc Andreesen 起的这个名字。由于商标问题以及很多产品已经使用了 Live 的前缀,网景市场部将它改名为 LiveScript。在1995年11月底,Navigator 2.0B3 发行,其中包含了该语言的原型,这个版本相比之前没有什么大的变化。在1995年12月初,Java 语言发展壮大,Sun 把 Java 的商标授权给了网景。这个语言被再次改名,变成了最终的名字——JavaScript。在之后的1997年1月,标准化以后,就成为现在的 ECMAScript。

近一两年在客户端上用到 JS 的地方也越来越多了,笔者最近接触了一下 JS ,作为前端小白,记录一下近期自己“踩坑”的成长经历。

一. 原始值和对象

在 JavaScript 中,对值的区分就两种:

1.原始值:BOOL,Number,String,null,undefined。

2.对象:每个对象都有唯一的标识且只严格的等于(===)自己。

null,undefined没有属性,连toString( )方法也没有。

false,0,NaN,undefined,null,' ' ,都是false。

typeof 运算符能区分原始值和对象,并检测出原始值的类型。

instanceof 运算符可以检测出一个对象是否是特定构造函数的一个实例或者是否为它的一个子类。

JavaScript 新手的踩坑日记

null 返回的是一个 object,这个是一个不可修复的 bug,如果修改这个 bug,就会破坏现有代码体系。但是这不能表示 null 是一个对象。

因为第一代 JavaScript 引擎中的 JavaScript 值表示为32位的字符。最低3位作为一种标识,表示值是对象,整数,浮点数或者布尔值。对象的标识是000,而为了表现 null ,引擎使用了机器语言 NULL 的指针,该字符的所有位都是0。而 typeof 就是检测值的标志位,这就是为什么它会认为 null 是一个对象了。

所以判断 一个 value 是不是一个对象应该按照如下条件判断:

function isObject (value) { return ( value !== null && (typeof value === 'object' || typeof value === 'function')); }

null 是原型链最顶端的元素

Object.getPrototypeOf(Object.prototype) < null

判断 undefined 和 null 可以用严格相等判断:

if(x === null) { // 判断是否为 null } if (x === undefined) { // 判断是否为 undefined } if (x === void 0 ) { // 判断是否为 undefined,void 0 === undefined } if (x != null ) { // 判断x既不是undefined,也不是null // 这种写法等价于 if (x !== undefined && x !== null ) }

在原始值里面有一个特例,NaN 虽然是原始值,但是它和它本身是不相等的。

NaN === NaN

原始值的构造函数 Boolean,Number,String 可以把原始值转换成对象,也可以把对象转换成原始值。

// 原始值转换成对象 var object = new String('abc') // 对象转换成原始值 String(123) <'123'

但是在对象转换成原始值的时候,需要注意一点:如果用 valueOf() 函数进行转换的时候,转换一切正确。

new Boolean(true).valueOf()

但是使用构造函数将包装对象转换成原始值的时候,BOOL值是不能正确被转换的。

Boolean(new Boolean(false))

构造函数只能正确的提取出包装对象中的数字和字符串。

二. 宽松相等带来的bug

在 JavaScript 中有两种方式来判断两个值是否相等。

严格相等 ( === ) 和严格不等 ( !== ) 要求比较的值必须是相同的类型。

宽松相等 ( == ) 和宽松不等 ( != ) 会先尝试将两个不同类型的值进行转换,然后再使用严格等进行比较。

宽松相等就会遇到一些bug:

undefined == null // undefined 和 null 是宽松相等的

关于严格相等( Strict equality ) 和 宽松相等( Loose equality ),GitHub上有一个人总结了一张图,挺好的,贴出来分享一下,Github地址在

JavaScript 新手的踩坑日记

但是如果用 Boolean( ) 进行转换的时候情况又有不同:

JavaScript 新手的踩坑日记

这里为何对象总是为true ?

在 ECMAScript 1中,曾经规定不支持通过对象配置来转换(比如 toBoolean() 方法)。原理是布尔运算符 || 和 && 会保持运算数的值。因此,如果链式使用这些运算符,会多次确认相同值的真假。这样的检查对于原始值类型成本不大,但是对于对象,如果能通过配置来转换布尔值,成本很大。所以从 ECMAScript 1 开始,对象总是为 true 来避免了这些成本转换。

三. Number
(责任编辑:ioter)

用户喜欢...

WebViewJavascriptBridge原理解析

我们的项目是一个OC与javascript重度交互的app,OC与javascript交互的那部分是在 的基础上修改的,WebViewJavascriptBridge应该是当前最流行最成功的OC与Web交互实现了。最近看了一下他的实现原理,顺...


iOS相机开发的踩坑篇

相机的设置,这个demo用GPUImageview为基准,做了一个基础的demo,处理了供底层OpenGL的方向处理,其他功能参考 最后的参考链接可以实现。 ps:2016年整年基本上都是做avfoundation的开发,自我感觉对...


微信小程序踩坑

本次开发微信小程序第一个版本,遇到如下问题: 关于小程序里引入iconfont 原有H5项目中iconfont.css里@font-face 引用的ttf等文件在小程序中不支持(小程序里请求资源都是https), 解决方法:知...