理解原型&原型链
函数即对象
在 JS 里,函数就是 Function 函数的实例对象
function Person() {}
var person1 = new Person();
var person2 = new Person();
typeof Person;
// ("function");
var person1 = new Person();
undefined;
typeof person1;
// ("object");
person1.constructor;
// ƒ Person() {}
上面代码 Person( )就是 person1 和 person2 的构造函数。
可以通过对象.constructor拿到创建该实例对象的构造函数
constructor 是一种用于创建和初始化 class 创建的对象的特殊方法.
如果没有显式指定构造方法,则会添加默认的 constructor 方法。
如果不指定一个构造函数(constructor)方法, 则使用一个默认的构造函数(constructor)。
prototype
几乎所有的 JavaScript 对象都是 Object 的实例;一个典型的对象继承了 Object.prototype 的属性(包括方法),尽管这些属性可能被遮蔽(亦称为覆盖)
prototype 对象用于放某同一类型实例的共享属性和方法,实质上是为了内存着想。
new 运算符
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。new 关键字会进行如下的操作:
- 创建一个空的简单 JavaScript 对象(即{});
- 链接该对象(即设置该对象的构造函数(例如 Object.prototype))到另一个对象 ;
- 将步骤 1 新创建的对象作为 this 的上下文 ;
- 如果该函数没有返回对象,则返回 this。
自己实现 new
function create(Con, ...args) {
let obj = {};
Object.setPrototypeOf(obj, Con.prototype);
// obj.__proto__ = Con.prototype
let result = Con.apply(obj, args);
return result instanceof Object ? result : obj;
}
- 首先函数接受不定量的参数,第一个参数为构造函数,接下来的参数被构造函数使用
- 然后内部创建一个空对象 obj
- 因为 obj 对象需要访问到构造函数原型链上的属性,所以我们通过 setPrototypeOf 将两者联系起来。这段代码等同于 obj.proto = Con.prototype
- 将 obj 绑定到构造函数上,并且传入剩余的参数
- 判断构造函数返回值是否为对象,如果为对象就使用构造函数返回的值,否则使用 obj,这样就实现了忽略构造函数返回的原始值
__proto__
是每个对象(除 null 外)都会有的属性,叫做__proto__,这个属性会指向该对象的原型
__proto__指向原型对象,原型对象中的constructor又指向构造函数