1、new 时构造函数的4个过程
(1)创建一个空对象,作为将要返回的对象实例。
(2)将空对象原型的内存地址__proto__
指向函数的原型对象。
(3)将利用函数的call方法,将原本指向window的绑定对象this指向了空对象
(4)开始执行构造函数内部的代码。
function Cat(name, age) {
var Cat = {}; // 声明一个空对象
Cat.name = name; // 把值赋值给新声明的Cat
Cat.age = age; // 同上
return Cat; // 返回这个对象
}
console.log(new Cat('miaomiao', 18)); // {name: "miaomiao", age: 18}
function Foo(name) {
this.name = name;
return this;
}
var obj = {};
obj.__proto__ = Foo.prototype;
// Foo.call(obj, 'mm');
var foo = Foo.call(obj, 'mm');
console.log(foo);
首先预编译,声明提升,解释执行。
执行时按照顺序来进行,
- obj指向空对象;
- obj的原型地址指向构造函数Foo的原型对象;
- 执行
Foo.call(obj, 'mm');
this.name = name;
通过函数的call方法将this绑定到obj(也就是说this就是obj),实参mm传入构造函数Foo中,这样this.name = 'mm',那么obj.name = 'mm',也就是说name属性被挂载到obj对象上。return this;
就是return obj,这样obj这个对象就被返回出来了。
- 将结果赋值给变量foo。
- 打印结果。
2、原型原型链的作用
就像盖房子用的砖头和水泥,平时对工作几乎没有影响,但是遇到bug、性能优化时,底层东西还是有用的。
3、什么是原型 是一个对象(每一个对象(null除外)在创建时都会与之关联另外一个对象,这另一个对象就是原型)
构造函数:每个函数都有一个原型 通过prototype访问。
function Person(){};
prototype是函数才有的属性
Person.prototype.name = 'Kevlin';
var person1 = new Person() // 构造person1实例
var person2 = new Person() // 构造person2实例
console.log(person1,person2) // Kevlin Kevlin
Person.prototype所指向的对象就是person1、person2的原型
示意图如下
对象:js的每个对象都有一个原型,通过__proto__访问到。
new 参考JS中的new操作符 - 见嘉于世 - 博客园