关于javascript冷门知识点的总结1

408 阅读3分钟

这是我参与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)