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时 执行垃圾回收
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
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和构造函数有关
- 啥叫 构造函数 ?
- 它们首先以大写字母命名。
- 它们只能由
"new"操作员执行。
function User(name) {
this.name = name;
this.test = false;
}
let user = new User("ppx");
alert(user.name); // ppx
2、new 做了什么事情 ?
- 创建一个
新的空对象,并分配给this。 - 函数体执行。通常它会修改
this,向其添加新属性。 - 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()
2、转数字
- 尝试
obj.valueOf()和obj.toString()
3、
默认情况下,普通对象具有以下toString和valueOf方法:
- 该
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