Object&Class
Object
Class
Definition
类是用于创建对象的模板,JS 中的类建立在原型之上,类实际上是“特殊的函数”
类的定义
类有两种定义方式:类表达式和类声明。
字段
类字段与对象属性相似,不属于变量,所以我们不需要使用诸如 const 一类的关键字去声明它们。
公共字段
公共字段使得实例可以获得属性
方法
方法是一种作为对象的属性的函数。
方法被定义在类实例的原型上并且被所有实例共享
class A {
testMethod() {
console.log("testMethod");
}
}
console.log(A.prototype.testMethod); // [Function: testMethod]
但是可以作为字段添加到类中,且可以保证 this
始终指向类的实例(或者类本身,对于静态字段):
class C {
a = 1;
autoBoundMethod = () => {
console.log(this.a);
};
}
const c = new C();
c.autoBoundMethod(); // 1
const { autoBoundMethod } = c;
autoBoundMethod(); // 1
// 如果这是普通方法,此时应该是 undefined
原因:
Arrow functions differ in their handling of this
: they inherit this
from the parent scope at the time they are defined.
Because a class's body has a this
context, arrow functions as class fields close over the class's this
context, and the this
inside the arrow function's body will correctly point to the instance (or the class itself, for static fields). However, because it is a closure, not the function's own binding, the value of this
will not change based on the execution context.
类字段是在实例(instance)上定义的,而不是在原型(prototype)上定义的,因此每次创建实例都会创建一个新的函数引用并分配一个新的闭包,这可能会导致比普通非绑定方法更多的内存使用。
继承和原型链
符号
someObject.[[Prototype]]
用于标识someObject
的原型。内部插槽[[Prototype]]
可以通过Object.getPrototypeOf()
和Object.setPrototypeOf()
函数来访问。这个等同于 JavaScript 的非标准但被许多 JavaScript 引擎实现的属性__proto__
访问器。它不应与函数的func.prototype
属性混淆,后者指定在给定函数被用作构造函数时分配给所有对象实例的[[Prototype]]
。
Function: prototype
类是一种特殊的函数,所以由类构造的对象的原型是类的 prototype
属性。
const a = {};
Object.getPrototypeOf(a) === Object.prototype; // true
几乎所有的 JavaScript 对象最终都继承自 Object.prototype
。
this 关键字
this
的值取决于它出现的上下文:函数、类或全局。
new 运算符
当一个函数被 new
关键字调用时,这个函数会被用作构造函数,new
会做以下几件事:
创建一个空白的纯 JavaScript 对象。接下来我们称其为
newInstance
如果构造函数的
prototype
是一个对象,则将newInstance
的[[Prototype]]
指向构造函数的prototype
属性,否则newInstance
将保持为一个纯 JavaScript 对象,而其[[Prototype]]
为Object.prototype
使用指定的参数执行构造函数,并将
newInstance
作为this
的上下文(即:构造函数中的所有this
引用都指向newInstance
)。如果构造函数返回一个非原始值,则该返回值作为整个
new
表达式的结果。否则(即未返回任何值或返回了一个原始值),newInstance
作为整个new
表达式的结果返回。