Skip to content

变量类型和计算

typeof能判断哪些类型

  • undefind string number boolean symbol
  • object (.typeof null === 'object' )
  • function

识别所有值类型

javascript
let a0
console.log(typeof a0) // undefined

const a1 = 'string'
console.log(typeof a1) // string

const a2 = 1
console.log(typeof a2) // number

const a3 = true
console.log(typeof a3) // boolean

const a4 = Symbol('a4')
console.log(typeof a4) // symbol

识别函数

javascript
console.log(typeof console.log) // function
console.log(typeof (() => {})) // function

判断是否是引用类型(不可在细分)

如需判断是否是数组,对象等,请用 instanceof

javascript
const a0 = null
console.log(typeof a0) //object

const a1 = { name: 'wcd' }
console.log(typeof a1) // object

const a2 = ['a']
console.log(typeof a2) // object

类型转化

强制类型转换:paresInt, ParseFloat, toString... 隐式类型转换:if, 逻辑运算,== ,拼接字符串

String or toString

String() or toString() 都是将其他类型的变量转换为字符串类型 toString() 无法转换 null 和 undefined

javascript
let a
let b = null

// console.log(a.toString()); // Cannot read property 'toString' of undefined
// console.log(b.toString()); // Cannot read property 'toString' of null
console.log(String(a)) // undefined
console.log(String(b)) // null

变量计算

字符串拼接

javascript
console.log(100 + 10) // 110
console.log(100 + '10') // '10010'
console.log(true + '10') // 'true10'

== 运算符

javascript
console.log(100 == '100') // true
console.log(0 == '') // true
console.log(0 == false) // true
console.log(false == '') // true
console.log(null == undefined) // true

/**
 * TODO: 偷懒写法,除 xx == null 之外,一律采用 ===
 * 其实jQuery与代码打包之后也是这样的形式,
 */
const obj = {
  name: 'wcd',
}
if (obj.age == null) {
  // ...
}

// 相当于
if (obj.age === null || obj.age === undefined) {
  // ...
}

if 语句与逻辑运算

javascript
// 经过两次非运算为 true 的为 truly 变量,反之则为 falsely
// truly 变量: !!a === true
// falsely 变量: !!a === false

const num = 100
console.log(!num) // false
console.log(!!num) // true

console.log(!!{}) // true

// 除此之外都是truly变量
console.log(!!0) // false
console.log(!!NaN) // false
console.log(!!'') // false
console.log(!!null) // false
console.log(!!undefined) // false
console.log(!!false) // false

逻辑判断

javascript
console.log(10 && 0) // 0
console.log('' || 'abc') // 'abc'
// TODO: window环境下测试
console.log(!window.abc) // true

原型和原型链

class 与 继承

类与继承

class的原型本质

javascript
class Parent {
  constructor(name = 'wcd') {
    this.name = name
  }
}
class Child extends Parent {}
console.log(new Child())

console.log(typeof Parent) // function
console.log(typeof Child) // function

// class的类型实际上是函数,所有可见class是语法糖

类型判断 instanceof

instanceof 与 typeof

instanceof 与 typeof 相比,instanceof 方法要求开发者明确的确认对象为某特定类型。 即 instanceof 用于判断引用类型属于哪个构造函数的方法。

javascript
const arr = []
console.log(arr instanceof Array) // true
console.log(typeof arr) // "object"

继承关系

instanceof 操作符用于检测对象是否属于某个 class,同时,检测过程中也会将继承关系考虑在内。

javascript
// 类
class Parent {}
const _Parent = new Parent()
console.log(_Parent instanceof Parent) // true

// 也可以是构造函数,而非 class
function GeParent() {}
const ge = new GeParent()
console.log(ge instanceof GeParent) // true

另外,更重的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。

javascript
// 判断 f1 是否是 Fn 类的实例 , 并且是否是其父类型的实例
function An() {}
function Fn() {}
Fn.prototype = new An()

var f1 = new Fn()
console.log(f1 instanceof Fn) // true
console.log(f1 instanceof An) // true

f1 instanceof Fn 的判断逻辑是:

  • f1 的 _proto_  一层一层往上,是否对应到 Fn.prototype
  • 再往上,看是否对应着 An.prototype
  • 再试着判断 f1 instanceof Object

原型和原型链

作用域和闭包

javascript
// 闭包作用
{
  // 闭包隐藏数据,只提供 API
  function createCache() {
    const data = {} // 闭包中的数据,被隐藏,不被外界访问
    return {
      set: function (key, val) {
        data[key] = val
      },
      get: function (key) {
        return data[key]
      },
    }
  }

  const c = createCache()
  c.set('a', 100)
  console.log(c.get('a'))
}

this

javascript
// 模拟 bind
Function.prototype.bind1 = function () {
  // 将参数拆解为数组
  const args = Array.prototype.slice.call(arguments)

  // 获取 this(数组第一项)
  const t = args.shift()

  // fn1.bind(...) 中的 fn1
  const self = this

  // 返回一个函数
  return function () {
    return self.apply(t, args)
  }
}

function fn1(a, b, c) {
  console.log('this', this)
  console.log(a, b, c)
  return 'this is fn1'
}

const fn2 = fn1.bind1({ x: 100 }, 10, 20, 30)
const res = fn2()
console.log(res)

写 var 与不写 var 有什么区别

javascript
// 思考:写 var 与不写 var 有什么区别

// 使用 var 关键字定义变量的时候,相当于在当前的作用域内声明了一个变量
// varFun函数声明 a1 变量,a1 相当于局部变量,只允许当前作用域内访问
// 如果不使用 var 相当于属性的赋值,相当于在window全局定义属性b

// delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。
// TODO: 可以验证变量跟属性

// var variable
var a = 1
console.log(a) // 1
delete a
console.log(a) // 1

b = 2
console.log(b) // 2
delete b
console.log(b) // b is not defined
;(function varFun() {
  var c = 3
  console.log(c) // 3
})()
console.log(c) // c is not defined

闭包题目

javascript
function fun(n, o) {
  console.log(o)
  return {
    fun: function (m) {
      return fun(m, n)
    },
  }
}

var a = fun(0)
a.fun(1)
a.fun(2)
a.fun(3) // undefined,0,0,0
var b = fun(0).fun(1).fun(2).fun(3) // undefined,0,1,2
var c = fun(0).fun(1) // undefined,0

解答:https://www.cnblogs.com/xxcanghai/p/4991870.html

参考

JavaScript instanceof 运算符深入剖析