这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
typeof
typeof对于定义了的变量但值为undefined
的变量会输出undefined,而未定义的变量和定义后不赋值的变量都会输出undefined
。
所以有一些安全防范机制,比如如下:
(function(){
function Feature() {
/* */
}
function doSomething() {
let helper = (typeof Feature !=='undefined')?
Feature:
function () {
console.log("123")
}
let val = helper()
}
doSomething()
})()
这里Feature不是个全局变量,但还是可以使用typeof的安全防范机制来做检查,也可以在浏览器环境下用window对象的属性来判断。
function doSomething2(Feature) {
let helper = Feature||function () {}
let val = helper()
}
代码简洁了很多
JavaScript七种内置类型:null,undefined,number,string,boolean,symbol,object
内部属性[[Class]]
可以使用Object.prototype.toString()
来访问数据类型在内核中的属性定义:
console.log(Object.prototype.toString.call([1,2,3]))// 内部属性-数组
console.log(Object.prototype.toString.call(/regex-literal/i))// 内部属性-正则
console.log(Object.prototype.toString.call(null))// 内部属性-Null
封装对象包装
object wrapper
由于基本类型没有length,toString()等方法,需要封装对象才能访问
let a = new Boolean(false)
console.log(typeof a)//Object自动转换为true
console.log(a)
if(a){//a 是true
console.log("aaa")
}
----------------------------------------------------------------
let a='abc'
let b = new String(a)//封装
let c = Object(a)//封装
console.log(typeof a,typeof b,typeof c)
console.log(b instanceof String ,c instanceof String )//true true
console.log(Object.prototype.toString.call(b),Object.prototype.toString.call(c))//[object String] [object String]
使用原生函数构造
- Array(..)
- Object(..)
- Function(..)
- RegExp(..)
- Date(..)
- Error(..)
- Symbol(..)
这里有一个类型比较特殊,就是
Symbol
类型,以及利用Symbol
实现类型的迭代属性。
什么是Symbol
这里用MDN文档的解释就是:symbol 是一种基本数据类型 (primitive data type)。Symbol()
函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()
"。
对于日常的开发使用,Symbol
一般不会使用太多,我们只需要记住它的特点是创建的数据具有唯一性,比如Symbol("a")===Symbol("a") //false
这样我们可以用它来构造对象的唯一属性,防止属性的重复以及原型链的冲突。
Symbol
比较出名的是它的一个属性iterator
,利用这个属性,我们可以为对象实现迭代器的属性,比如使用for ... of ...
来遍历一个实现Symbol.iterator
的对象。
下面用一段简单的代码来看看
var randoms = {
[Symbol.iterator]: function () {
return {
next: function () {
return {
value: Math.floor(Math.random() * 10),
}
},
}
},
}
var randoms_pool = []
for (var n of randoms) {
console.log(n)
randoms_pool.push(n)
if (randoms_pool.length === 10) break
}
console.log(randoms_pool)
上面的代码我们为randoms实现了Symbol.iterator
属性,每次迭代会产生一个随机数。这样其实可以将对象randoms
用一个数组的迭代方法来遍历。
运算符 && || ? :
优先级:&& > || > ?,:
运算符的关联
在&&和||多次出现时,采用左关联方式:从左向右执行,所以a && b && c
会被处理为(a&&b)&&&c
而? :是右关联,即 a ? b : c ? d : e
会被处理为a ? b :(c ? d : e)
,还有一个右关联的例子是 "="运算符,var a,b,c;a = b = c = 1
,首先执行的是c=1,然后是b=... ,c=... 。
let a = 1;
let b = 'foo';
let c = false;
let d = a && b || c ? c ||b ? a: c && b : a;
//((a && b) || c) ? ((c || b) ? a :(c && b)) : a
console.log(d)