Js基础——持续更新

四则运算
// 只有当加法运算时,其中一方是字符串类型,就会把另一个也转为字符串类型。其他运算只要其中一方是数字,那么另一方就转为数字。
console.log(1 + '1')                // '11' 加法只要一方是字符串,就会将另一方转化为字符串
console.log(+ '1')                  // 1    + 具有转义的作用,只有+的时候,会将之后转为number类型
console.log(+ 'a')                  // NAN  Number('a') => NaN
console.log(1 + + '1')              // 2
console.log('1' + + '1')            // '11'
console.log('a' + + 'b')            // 'aNaN'
console.log(1 + !0)                 // 2    ! 的优先级高于+ 所以会先计算!0 结果为true 1 + true => 2
console.log(1 + !1)                 // 1
== 操作符
// == 操作符

console.log(NaN == NaN);            // false  == 操作符 会将两侧数据的typeof转换 NaN是number类型 但是不会相等
console.log(0 == -0);               // true
console.log(null == undefined);     // true
console.log(1 == '1');              // true     数字和字符串比较,会将字符串转换为数字
console.log(1 == false);            // false    数字和布尔值比较,会将布尔值转换为数字
console.log(0 == {});               // false    对象比较时,会先转化为基本类型,空对象会转为[object object],所以typeof ({})的值为NaN
console.log(0 == []);               // true     typeof ([])的值为'' 字符串又会被转化为数字
console.log([] == ![]);             // true     !的优先级高 ![]的值为true  [] == false => [] == 0 => '' == 0 => 0 == 0

// 对象转普通类型会经过两个过程
function toPrimitive (obj) {
    if (obj.valueOf()) return obj.valueOf()
    if (obj.toString()) return obj.toString()
}

toPrimitive({a: 1});
执行上下文

https://yanhaijing.com/javascript/2014/04/29/what-is-the-execution-context-in-javascript/

  • [ ] 种类

    • [ ] 全局上下文 => 首次加载会默认执行
    • [ ] 函数上下文 => 函数调用时会执行
  • [ ] 要点

    • [ ] 单线程
    • [ ] 同步执行
    • [ ] 一个全局上下文
    • [ ] 无限制函数上下文
    • [ ] 每次函数被调用创建新的执行上下文,包括调用自己
    b() // call b
    console.log(a) // undefined
    
    var a = 'Hello world'
    
    function b() {
    console.log('call b')
    }

    脚本运行首先会默认创建 全局上下文放入栈顶,值为undefined,在调用b方法的时候,创建了函数执行上下文console.log('call b')放入栈顶,一旦上下文执行完毕,它将被从栈顶弹出,并将控制权返回给下面的上下文,直到只剩全局上下文能为止。

    b() // call b second
    
    function b() {
    console.log('call b fist')
    }
    function b() {
    console.log('call b second')
    }
    var b = 'Hello world'

    在提升的过程中,相同的函数会覆盖上一个函数

闭包
  • [ ] 什么是闭包?

    • [ ] 函数 A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B 就被称为闭包。
    function A() {
    let a = 1
    function B() {
        console.log(a)
    }
    return B
    }
  • [ ] 闭包的作用是什么

    • [ ] 减少全局变量的产生,起到隔离的作用,使一个方法可以访问另一个方法中的变量
  • [ ] 闭包的缺点是什么

    • [ ] 产生的变量不被销毁,不被使用,容易引起内存泄漏
  • [ ] 如何解决闭包的缺点

    • [ ] 使用后将闭包赋值为null
    // 闭包
    
    function other () {
    let a = 1;
    function closure () {       // closure是一个闭包
        a++;
        console.log(a);
    }
    return closure
    }
    
    let bus = other();                // 接受闭包
    
    bus();                            // 执行
    bus();
    
    bus = null;                       // 销毁
深浅拷贝

延伸阅读:

基本类型存储在栈中,对象存储在堆中,let b = {a: 1}时,b存储于栈中,他指向堆中的对象

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

如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。

  • [ ] 浅拷贝

    • [ ] Object.assign
    let a = {
      age: 1
    }
    let b = Object.assign({}, a)
    a.age = 2
    console.log(b.age) // 1
    • [ ] 展开运算符(…)
    let a = {
      age: 1
    }
    let b = {...a}
    a.age = 2
    console.log(b.age) // 1
  • [ ] 深拷贝

    • [ ] JSON.parse(JSON.stringify(object))
    let a = {
      age: 1,
      jobs: {
          first: 'FE'
      }
    }
    let b = JSON.parse(JSON.stringify(a))
    a.jobs.first = 'native'
    console.log(b.jobs.first) // FE

    会忽略 undefined

    不能序列化函数

    不能解决循环引用的对象

猜你喜欢

转载自blog.csdn.net/Nick_YangXiaoTong/article/details/81209424