《You dont know JS》类型篇总结
2018-01-25 15:21
232 查看
类型
javaScript中的类型和熟知的一些强类型语言的有关类型的定义是不一样的。在js中,类型的含义是值的内部特征,它定义了值得行为,以使其区别于其他值。(a type is an intrinsic, built-in set of characteristics that uniquely identifies the behavior of a particular value and distinguishes it from other values)。由此我们就可以看出,js强调的是值的行为,js认为拥有不同行为的值就是不同类型的值,而根据不同行为进行分类,js区分了七种类型:Undefined、Null、Boolean、Number、Object以及ES6新增的Symbol。
一:null和object
typeof null === 'object'; // true typeof {} === 'object'; // true
在js中,null被当做object,这是js的一个BUG,修复这个BUG的代价有些大,所以相当时间内不会有什么变化,所以为了准确区分null和object,可以借助取反运算符,如下所示:
!null === true; // true !{} === false; // true var a = null; if (!a && typeof a === 'object') { // 为true时,a为null ... }
如上所示,借助这个区别,我们就可以准确区分null和object了。
二:typeof function a() {} === 'function'
如标题所示的结果为true。'function'是object的一个“子类型”。函数是“可调用对象”,它有一个内部属性[[Call]],该属性使其可以被调用。typeof [1,2,3] === 'object'; // true
同理,数组也是对象,也是object的一个“子类型”。
三:JS中的变量没有类型,值有类型
JS中的变量并不具有类型,所以变量存储的值可以是任意类型且是动态可变的。所以我们说JS是一种“弱类型语言”。所以,我们在使用typeof检查类型时,检查的并不是变量的类型,而是该变量存储的值的类型。因为JS中的变量没有类型。注意:typeof运算符的返回值总是一个字符串。
四:区分undefined和undeclared
undefined:未赋值undeclared:未定义
在js中,undefined表示变量本身已经定义,但是还没有对该变量赋值或者被显示的赋值为undefined。如下所示:
var a; typeof a; // 'undefined' var c = 2; typeof c; // 'number' c = a; typeof c; // 'undefined'
与undefined形成鲜明对比的,就是undeclared。如果我们完全还没声明,就直接去调用(注意,这里是直接调用未声明的变量),就会报错,如下所示:
var a; a; // 'undefined' c; // 'Uncaught ReferenceError: c is not defined'
"c is not defined"并非字面意思表示未定义,这也是为什么要引入一个"undeclared",因为在此处"c is not declared"更准确一些。
但需要注意的一点是,不论是对于已经定义未赋值的变量,还是对于未定义的变量,typeof操作符都会返回"undefined"。
var a; typeof a; // undefined typeof c; // undefined
会出现上述这种奇怪的现象,是typeof有一个特殊的安全防范机制。这种安全机制还是比较有用的。我觉得大家都写过如下所示的这种代码,但我们需要使用一个变量时,为了避免一些不必要的操作,可能会先对该变量做一个判断:
var name = '' if (name) { // 如果name的值是空字符串,就不输出 console.log(name); } if (age) { // 如果age的值是小于等于0的值,就不输出 console.log(age); }
现在我们知道,如上所示的代码是存在安全隐患的,我们无法保证name和age都是已经声明过得变量,这就存在安全隐患。这就需要做一个安全验证,这时候typeof的安全机制就有了用处:
var name = ''; if (typeof name !== 'undefined' && name) { // 如果name的值是空字符串,就不输出 console.log(name); } if (typeof age !== 'undefined' && age) { // 如果obj.age的值是小于等于0的值,就不输出 console.log(age); }
同时,typeof操作符还可以验证某个变量当前是否有定义,避免同名覆盖。
if (typeof a === 'undefined') { a = {...}; }
当然,如果是访问对象的一个不存在的属性,是不会像访问未声明的变量那样报错的。
var obj = { name : 'abc' } if (obj.name) { // obj.name => 'abc' console.log(obj.name); // 'abc' } if (obj.age) { // obj.age => 'undefined' console.log(obj.age); }
相关文章推荐
- JavaScript-读 You Dont Know JS,this到底是什么
- 《You dont know JS》原生函数
- You-Dont-Know-JS
- 《You dont know JS》值相关总结
- JavaScript-读 You Dont Know JS, Object到底是什么
- 《You dont know JS》强制类型转换
- JavaScript-读 You Dont Know JS,原型继承不是继承
- https://github.com/oneuijs/You-Dont-Need-jQuery
- Note On <You Don't Know JS - Scope and Closures>
- 5ThingsToKnowBeforeYouGetStartedWithAngulerJS
- You Don't Know JS: Types & Grammar 总结
- Note On <You Don't Know JS - this and Object Prototypes>
- You don't know js
- Most Enjoyable DisOrDats on YouDontKnowJack.com
- Node.js modules you should know about: request
- 《You Don't Know JS》
- if you dont know where to go, it doesnt matter which way to go.
- So, you think you know JavaScript? (你认为你懂JS吗)
- 读书笔记——You Don't Know Js Up & Going
- 读you don't know js 有感之作用域