构造函数和实例化
js
中可以通过构造函数批量创建对象,创建的过程通过new
关键词实现,这个过程也叫实例化,实例化的对象具有默认的属性和原型方法
1 2 3 4 5 6 7 8 9 10 11
| function Person(name, age) { this.name = name; this.age = age; }
Person.prototype.sayHello = function() { console.log(`My name is ${this.name}, I'm ${this.age} years old`); }
const jsonya = new Person('jsonya', 25); jsonya.sayHello();
|
new
的过程做了什么?
- 创建一个空对象
- 将这个空对象的原型指向构造函数的原型
- 执行构造函数,并将默认属性挂载到这个空对象上
- 判断构造函数的返回值,如果是对象则返回这个对象,否则返回这个空对象
模拟new
关键字?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function New() { const obj = {}; const Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; const result = Constructor.apply(obj, arguments); return result instanceof Object ? result : obj; }
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`my name is ${this.name}, I'm ${this.age} years old`); }
const jsonya = New(Person, 'jsonya', 25); jsonya.sayHello();
|
ok,实现了一个new
了,但其实我们通过分析原生的new方法可以看出,在new一个函数的时候,会返回一个func
同时在这个func
里面会返回一个对象Object
,这个对象包含父类func的属性以及隐藏的__proto__
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function New(Constructor) { return function() { const obj = {}; obj.__proto__ = Constructor.prototype; const result = Constructor.apply(obj, arguments); return result instanceof Object ? result : obj; } }
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`my name is ${this.name}, I'm ${this.age} years old`); }
const jsonya = New(Person)('jsonya', 25); jsonya.sayHello();
|
可以看出我们的第二种实现原理上是一致的 ,只不过我们将构造函数和参数区分开了