在JavaScript中,几乎所有的对象都是Object
类型的实例,它们都会从Object.prototype
继承属性和方法。Object
构造函数为给定值创建一个对象包装器。
Object
构造函数,会根据给定的参数创建对象,具体有以下情况:
- 如果给定值是
null
或undefined
,将会创建并返回一个空对象 - 如果传进去的是一个基本类型的值,则会构造其包装类型的对象
- 如果传进去的是引用类型的值,仍然会返回这个值,经他们复制的变量保有和源对象相同的引用地址
当以非构造函数形式被调用时,Object
的行为等同于 new Object(),具体如下:
- 使用带有可选属性列表的花括号
{…}(字面量)
来创建对象。
let user = { // 一个对象 name: "John", // 键 "name",值 "John" age: 30 // 键 "age",值 30 };
// 使用点属性读取文件的属性: alert( user.name ); // John alert( user.age ); // 30//可以添加或者修改属性
user.isAdmin = true;// 使用delete操作符移除属性
delete user.age;
属性
变量名不能是编程语言的某个保留字,如for
、let
、return
等,
但对象属性名不受到此限制,可以是任何字符串或者symbol
(其他类型会被自动地转换为字符串)
// 这些属性都没问题 let obj = { for: 1, let: 2, return: 3 };alert( obj.for + obj.let + obj.return ); // 6
检查属性是否存在的操作符 "in"
let user = { name: "John", age: 30 };
alert( "age" in user ); // true,user.age 存在
alert( "blabla" in user ); // false,user.blabla 不存在。
对象有顺序,整数属性会被进行排序,其他属性则按照创建的顺序显示。
这里的整数属性指的是一个可以在不做任何更改的情况下与一个整数进行相互转换的字符串。
引用和拷贝
对象通过引用被赋值和拷贝。换句话说,一个变量存储的不是“对象的值”,而是一个对值的“引用”(内存地址)。因此,拷贝此类变量或将其作为函数参数传递时,所拷贝的是引用,而不是对象本身。
为了创建“真正的拷贝”(一个克隆),我们可以使用 Object.assign
来做所谓的“浅拷贝”(嵌套对象被通过引用进行拷贝)或者使用“深拷贝”函数,例如 _.cloneDeep(obj)。
垃圾回收
可达性
当前函数的局部变量或参数、嵌套调用时调用链上所有的函数的变量和参数、全局变量等值被称为roots
如果一个值可以通过引用或引用链从根访问任何其它值,则该值为可达。
关于垃圾回收我之后会单独开一个长篇来介绍
V8 垃圾回收原来这么简单? - 知乎 (zhihu.com)
内存管理 - JavaScript | MDN (mozilla.org)
对象方法,“this”
this
指的是“当前的对象”,this
的值是运行时绑定的,且指向当前执行上下文。
全局上下文
无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this
都指向全局对象。