JS基础知识点(二)

100 阅读2分钟

== vs ===

对于 == 来说,如果对比双方的类型不一样的话,就会进行类型转换

假如我们需要对比 xy 是否相同,就会进行如下判断流程:

  1. 首先会判断两者类型是否相同。相同的话就是比大小了
  2. 类型不相同的话,那么就会进行类型转换
  3. 会先判断是否在对比 nullundefined,是的话就会返回 true
  4. 判断两者类型是否为 stringnumber,是的话就会将字符串转换为 number

    1 == '1'
          ↓
    1 ==  1

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断

'1' == true'1' ==  1
        ↓
 1  ==  1

6.判断其中一方是否为 object 且另一方为 stringnumber 或者 symbol,是的话就会把 object 转为原始类型再进行判断

'1' == { name: 'yck' }
        ↓
'1' == '[object Object]'

'[object Object]' == { name: 'yck' } // true

对于 === 来说就简单多了,就是判断两者类型和值是否相同。

闭包

闭包的定义其实很简单:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。

function A() {
  let a = 1
  window.B = function () {
      console.log(a)
  }
}
A()
B() // 1

在 JS 中,闭包存在的意义就是让我们可以间接访问函数内部的变量。

循环中使用闭包解决 `var` 定义函数的问题

第一种是使用闭包的方式


for (var i = 1; i <= 5; i++) {
  (function(j) {
    setTimeout(function timer() {
      console.log(j)
    }, j * 1000)
  })(i)
}

第二种就是使用 setTimeout 的第三个参数,这个参数会被当成 timer 函数的参数传入

for (var i = 1; i <= 5; i++) {
  setTimeout(
    function timer(j) {
      console.log(j)
    },
    i * 1000,
    i
  )
}

第三种就是使用 let 定义 i 了来解决问题了,这个也是最为推荐的方式

for (let i = 1; i <= 5; i++) {
  setTimeout(function timer() {
    console.log(i)
  }, i * 1000)
}

深浅拷贝

对象类型在赋值的过程中其实是复制了地址,从而会导致改变了一方其他也都被改变的情况。通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝来解决这个情况。

let a = {
  age: 1
}
let b = a
a.age = 2
console.log(b.age) // 2

浅拷贝

首先可以通过 Object.assign 来解决这个问题,很多人认为这个函数是用来深拷贝的。其实并不是,Object.assign 只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝。

let a = {
  age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1