JS实用篇复习笔记(8)

263 阅读4分钟

1、垃圾收集算法

1、标记清除整理算法(常用)
    1、先分类标记(先标记第一层根,然后标记引用部分)
    2、清除
    3、整理保持连续

2、引用计数算法 
    1、对象被引用一次 记数 +1 
    2、减少一次引用 计数 -1
    3、当引用计数 =0 时  则清除


3、当前 不能删除的对象
-   当前正在被调用执行的函数,它的局部变量和参数。
-   当前嵌套调用链上的其他函数、它们的局部变量和参数。
-   全局变量。
-   还有函数内部的闭包引用

4、举几个例子

1、单个对象

    // ppx has a reference to the object 
    let ppx = { job: "dev" };
    // 这个 job 明显是个全局变量,存在于全局,暂时无法回收 ,那怎么回收?
     ppx = null 

2、对象copy

// user has a reference to the object
let ppx = {
  job: "dev"
};

let test = ppx; 
// 当前test 具有对象 引用, 当前使得 ppx = null 但 test还会存在  当 test=null时 执行垃圾回收

image.png

3、互相引用

function team(man, woman) {
      woman.boyfriend = man;
      man.girlfriend = woman;

      return {
        one: man,
        two: woman,
      };
    }

    let like = team(
      {
        name: "Mark",
      },
      {
        name: "ppx",
      }
    );

这是个典型的相互引用案例,你可在 控制台查看

如果想去除一个的引用 使用 delete 删除 所有输入即可

delete like.one;
delete like.two.boyfriend;

2、说一说 this

1、this 取决于上下文

let user = {
  name: "ppx",
  age: 18,

  sayHi() {
// "this" is the "current object"
    alert(this.name);
  }

};

user.sayHi(); // ppx
  • 下面这个更加典型,对应上了
let user = { name: "ppx" };
let admin = { name: "test" };

function sayHi() {
  alert( this.name );
}

// use the same function in two objects
user.f = sayHi;
admin.f = sayHi;

// these calls have different this
// "this" inside the function is the object "before the dot"
user.f(); // ppx  (this == user)
admin.f(); // test  (this == admin)

2、当this未指向对象时为 undefined

  • 当以“方法”语法调用函数时:object.method()this调用期间的值为object
function sayHi() {
  alert(this);
}

sayHi(); // undefined 浏览器中执行会产生这个结果 [object Window] 指向window

  • like this one

image.png

3、箭头函数 this 规则

  • 箭头函数 不绑定 this
let user = {
  name: "ppx",
  sayHi() {
    let test = () => alert(this.name);
    test();
  }
};

user.sayHi(); // ppx 此处拿到的是 user.name 外层作用域的this

4、给出题目 试试

//这个 结果是什么 ?
  function makeUser() {
      return {
        name: "John",
        ref: this,
      };
    }

    let user = makeUser();

    alert(user.ref.name); //user.ref--> [object Window] window.name 没有
// 如何实现一个对话框式的计算器 ?
    let calculator = {
      sum() {
        return this.a + this.b;
      },
      mul() {
        return this.a * this.b;
      },
      read() {
        this.a = +prompt("a?", 0);
        this.b = +prompt("b?", 0);
      },
    };

    calculator.read();
    alert(calculator.sum());
    alert(calculator.mul());



3、说一说 new

1、new和构造函数有关

  • 啥叫 构造函数 ?
  1. 它们首先以大写字母命名。
  2. 它们只能由"new"操作员执行。
function User(name) {
  this.name = name;
  this.test = false;
}

let user = new User("ppx");

alert(user.name); // ppx

2、new 做了什么事情 ?

  1. 创建一个新的空对象,并分配给this
  2. 函数体执行。通常它会修改this,向其添加新属性
  3. return this
  • 使用 刚才的例子说明 new User("ppx")做了什么事情? 非常的明确
function User(name) {
// 1 this = {};  (implicitly)

// 2 add properties to this
  this.name = name;
  this.test = false;

// 3 return this;  (implicitly)
}

4、Symbol

  • Symbol 是唯一标识符的原始类型

1、希望同名符号相等,那么我们应该使用全局注册表:Symbol.for(key)返回(如果需要,创建)一个全局符号key作为名称

2、

// id is a new symbol
let id = Symbol();

创建时,我们可以给符号一个描述(也称为符号名称),主要用于调试目的:

// id is a symbol with the description "id"
let id = Symbol("id");

3、 注意 具有相同描述的符号——它们不相等:

let id1 = Symbol("id");
let id2 = Symbol("id");

alert(id1 == id2); // false

4、符号不会自动转换为字符串

let id = Symbol("id");
alert(id); // TypeError: Cannot convert a Symbol value to a string

语言保护机制,字符串和符号从根本上是不同的,不应意外地将它们转换为另一种

如果我们真的想显示一个符号,我们需要明确地调用.toString()

let id = Symbol("id");
alert(id.toString()); // Symbol(id), now it works

获取symbol.description属性显示描述:

let id = Symbol("id");
alert(id.description); // id

5、注意 符号属性不参与for..in循环

也不参与 Object.keys(user)

4、对象 转化

1、转为字符串

  • 尝试 obj.toString()obj.valueOf() image.png

2、转数字

  • 尝试 obj.valueOf()obj.toString()

image.png

3、 默认情况下,普通对象具有以下toStringvalueOf方法:

  • toString方法返回一个字符串"[object Object]"
  • valueOf方法返回对象本身
  • 举个例子
let user = {name: "John"};

alert(user); // [object Object]
alert(user.valueOf() === user); // true

4、有趣的事情

  • '*' 会进行数字转化
let obj = {
  // toString handles all conversions in the absence of other methods
  toString() {
    return "2";
  }
};

alert(obj * 2); // 4, object converted to primitive "2", then multiplication made it a number
  • '+' 会进行字符串连接
let obj = {
  toString() {
    return "2";
  }
};

alert(obj + 2); // 22 ("2" + 2), conversion to primitive returned a string => concatenation