JS 复习笔记

关于变量提升

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

  • 创建 变量,在内存中开辟空间
  • **初始化 **变量,将变量初始化为 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

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

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

事件冒泡

Click here!

上面的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 复习笔记)