创建对象的几种方式
- 利用对象字面量创建对象
const obj = {}
2.利用 new Object创建对象
const obj = new Object()
3.使用 构造函数实例化对象
function Fn(name) {
this.name = name
}
const obj = new Fn('张三')
console.log(obj.name); //张三
为什么要用构造函数的形式?
有同学可能会问:我们用对象字面量创建对象不是很方面快捷吗,为啥会出现构造函数这种繁琐的创建方式呢?
因为第1,2种方式只比较适用于我们需要创建少量对象时,而如果我们要创建很多个对象,且每个对象的属性有很多属性相同时,我们再用对象字面量去创建对象的话,就会显得代码很冗余了。如:
而我们使用构造函数创建的话,只需这样:
function Fn(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
const peiqi = new Fn('佩奇', 6, '女')
const qiaozi = new Fn('乔治', 3, '男')
const mon = new Fn('猪妈妈', 26, '女')
const dad = new Fn('猪爸爸', 28, '男')
实例化对象时的new到底做了什么呢?
- 创建一个空对象
- 设置原型链: 把空对象的__proto__属性指向构造函数的prototype对象
- 执行构造函数:并进入构造函数Fn中执行操作,把this指向新创建的对象
- 返回对象(如果构造器没有手动返回对象,则返回第一步的对象)
function Fn(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
// 模拟new实例化过程
function myNew(constructorFn, ...args) {
const obj = {}
obj.__proto__ = constructorFn.prototype
const result = constructorFn.apply(obj, args)
return typeof result === 'object' ? result : obj
}
const cat = new myNew(Fn, '机器猫', 28, '男')
为什么要执行第二点,即设置原理链
是为了共享构造函数原型中的属性和方法: obj.proto = constructorFn.prototype
function Fn(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
Fn.prototype.say = function () {
console.log('sayHi');
}
function myNew(constructorFn, ...args) {
const obj = {}
//这样实例化出来的对象就可以使用原型对象中的属性和方法啦
obj.__proto__ = constructorFn.prototype
const result = constructorFn.apply(obj, args)
return typeof result === 'object' ? result : obj
}
const cat = new myNew(Fn, '机器猫', 28, '男')
原型链总结
- 每个构造函数都有一个prototype属性,该属性指向原型对象,原型对象用来给各个实例化对象共享属性和方法。
- 每个实例化对象都有一个__proto__属性,该属性也指向原型对象。