美文网首页
JS 复习笔记

JS 复习笔记

作者: 滑天下之大稽 | 来源:发表于2020-02-25 22:05 被阅读0次

    关于变量提升

    使用关键字给变量赋值可以分为三个阶段:

    • 创建 变量,在内存中开辟空间
    • **初始化 **变量,将变量初始化为 undefined
    • 给变量 赋值

    对于letvarfunction:

    • let创建 过程被提升了,但是 初始化 没有被提升
    • var创建初始化 都被提升了
    • function创建初始化赋值 都被提升了

    🌰 关于 let 声明的变量是否存在 变量提升 ?

    let name = 'Catalina';
    {
        console.log(name); // Uncaught ReferenceError: name is not defined
        let name = 'Mozila';
    }
    

    如果 let 声明的变量不存在变量提升 ,console.log(name) 就会输出外层作用域的 name Catalina,结果却抛出了 ReferenceError,这很好的说明 let 也能变量提升,只是它存在“暂时死区”,在变量未初始化赋值前不能被访问。

    事件的三两事

    javascript dom 事件传播的三个阶段

    捕获 -> 目标 -> 冒泡

    说明:在捕获阶段,事件通过父元素向下传递到目标元素。 然后它到达目标元素,冒泡开始。

    img

    event.target

    <div onclick="console.log('first div')">
      <div onclick="console.log('second div')">
        <button onclick="console.log('button')">
          Click!
        </button>
      </div>
    </div>
    

    上面点击按钮时 event.targetbutton 元素。

    导致事件的最深嵌套元素是事件的目标。

    事件冒泡

    <div onclick="console.log('div')">
      <p onclick="console.log('p')">
        Click here!
      </p>
    </div>
    

    上面的html再点击后会先后输出 pdiv

    在事件传播期间,有三个阶段:捕获,目标和冒泡。 默认情况下,事件处理程序在冒泡阶段执行(除非您将useCapture设置为true)。 它从最深的嵌套元素向外延伸。

    JavaScript全局执行上下文为你创建了两个东西:全局对象和this关键字

    基本执行上下文是全局执行上下文:它是代码中随处可访问的内容。

    使用对象作为另一个对象的 key

    const a = {};
    const b = { key: "b" };
    const c = { key: "c" };
    
    a[b] = 123;
    a[c] = 456;
    
    console.log(a[b]);
    // 456
    

    对象的 key 值永远都是字符串,如果使用其他类型的值作为对象的 key,会先被使用 toString 方法转换成字符串。 b是一个对象,把它当作 key 使用时 先被转成字符串 "[object Object]",其实等式等于:

    a["[object Object]"] = 123;
    

    c也是这个原理:

    a["[object Object]"] = 456;
    

    等同于给这个字段覆盖了新值。

    所以最后等于 456

    手写 new

    new 操作符创建一个实例,做了四件事情:

    1. 创建一个空对象({}
    2. 链接该对象(即设置该对象的构造函数)到另一个对象
    3. this 的上下文设置为新创建的空对象
    4. 如果该函数没有返回对象(比如,基础类型值),则返回 this
    function _new(Fn, ...args) {
        if (typeof Fn !== 'function') {     // 如果不是函数,排除不是构造函数
            throw 'Frist arg must be a function';
        }
        let obj = {}, res;                  // 创建空对象,用来设置 this 上下文,当作构造函数的实例
        obj.__proto__ = Fn.prototype;       // 链接实例的 __proto__ 到构造函数
        // obj = Object.create(Fn.prototype)
        res = Fn.call(obj, ...args);        // 生成的新对象会绑定到函数调用的`this`
        return res instanceof Object ? res : obj
    }
    

    匿名函数二三

    1. 本应匿名的函数如果设置了函数名,在函数之外是无法调用这个函数的,但是在函数体内部是可以调用这个函数名变量。
    2. 而且类似于创建常量一样,这个名字存储的值是不能修改的(普通模式下不报错,但是没有任何效果;严格模式下会直接报错)
    var b = 10;
    (function b() {
        b = 20;
        console.log(b);
    })();
    console.log(b)
    /**
    ƒ b() {
        b = 20;
        console.log(b);
    }
    10
    */
    

    使用 严格模式

    var b = 10;
    (function b() {
        "use strict";
        b = 20;
        console.log(b);
    })();
    console.log(b)
    /**
    VM20050:4 Uncaught TypeError: Assignment to constant variable.
    */
    

    Array.prototype.push

    let obj = {
        2: 3,
        3: 4,
        length: 2,
        push: Array.prototype.push,
    }
    obj.push(1);
    obj.push(2);
    console.log(obj);
    

    可以先考虑 push 的实现方法,可以简单的如下模拟:

    Array.prototype.push = function(xx) {
        this[this.length] = xx
        // this.length ++
        return this.length
    }
    

    当执行 obj.push(1) 的时候, obj[obj.length] = 1,于是 obj[2] = 1

    当执行 obj.push(2) 的时候, obj[obj.length] = 2,于是 obj[3] = 2

    最后输出 {2: 1, 3: 2, length: 4, push: ƒ}

    相关文章

      网友评论

          本文标题:JS 复习笔记

          本文链接:https://www.haomeiwen.com/subject/wcwqchtx.html