本文已参与「新人创作礼」活动,一起开启掘金创作之路。详情
总结一下可以创建对象的共10种方式。
1. new Object()
var obj = new Object()
obj.name = '小明'
obj.say = function() {
console.log(this.name);
}
缺点: 步骤多
2. 使用字面量定义
var obj={num: 3}
缺点: 如果反复创建多个对象,代码会很冗余
3. 工厂函数
function createPerson(name,age) {
var o = new Object();
o.name = name;
o.age = age;
o.say = function(){ alert(this.name); }
return o;
}
var p1 = createPerson(“lilei",11);
缺点: 本质还是Object(),将来无法根据对象的原型对象准确判断对象的类型
4. 构造函数
// 1.定义构造函数:统一的属性结构和方法
function Student(sname, sage){
this.sname=sname;
this.sage=sage;
this.intr=function(){ … }
}
// 2. 使用new反复创建新对象
var lilei=new Student(“Li Lei”,11)
缺点: 如果构造函数中包含方法,则重复创建,浪费内存
5. 借助原型对象
先创建完全相同的对象,再给子对象添加个性化属性。
function Person() {
}
Person.prototype.name = '无名';
Person.prototype.age =11;
Person.prototype.say = function(){
console.log(this.name);
};
var p1 = new Person(); // 创建一个实例p1
p1.name='Li Lei' // 不会修改共有属性,而是自动修改实例自有属性
var p2 = new Person(); // 创建实例p2
p2.name = 'Han Meimei'; // 同上
console.log(p1);
console.log(p2);
缺点:步骤繁琐
6. 混合模式:
先创建完全相同的对象,再给子对象添加个性化属性。
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.say = function(){
console.log(this.name);
};
var p1 = new Student('Li Lei',11);
var p2 = new Student('Han Meimei', 12);
console.log(p1);
console.log(p2);
缺点:不符合面向对象封装的思想——定义person的属性和其原型上方法的定义分离
7. 动态混合
先创建完全相同的对象,再给子对象添加个性化属性。
function Person(name, age) {
this.name=name;
this.age=age;
if(Person.prototype.say===undefined){
Person.prototype.say = function(){
console.log(this.name);
};
}
}
var p1 = new Student('Li Lei',11,'初一2班');
var p2 = new Student('Han Meimei', 12 ,'初二2班');
缺点: 语义不符,其实if只在创建第一个对象时有意义。
8. 寄生构造函数
构造函数里调用其他的构造函数
function Person(name, age) {
this.name=name;
this.age=age;
if(Person.prototype.say===undefined){
Person.prototype.say = function(){
console.log(this.name);
};
}
}
function Student(name, age, className) {
var p = new Person(name,age); //借鸡生蛋
p.className=className
return p;
}
var p1 = new Student('Li Lei',11,'初一2班');
var p2 = new Student('Han Meimei', 12 ,'初二2班');
缺点: 可读性差。
9. ES6 class
什么是Class:程序中专门集中保存一种类型的所以子对象的统一属性结构和方法定义的程序结构。
怎么定义class:
1. 用`class{...}`包裹原构造函数+原型对象方法
2. 原构造函数名升级为整个class的名字,所有构造函数统一更名为 `constructor`
3. 原型对象中的方法,不用再加prototype前缀,也不用=function,直接 简写为: 方法名(){ ... ...}
class Person{
// constructor即为构造函数
constructor(name, age) {
this.name = name
this.age = age
}
// class中的方法其实是保存在原型对象中的
say() {
console.log(this.name);
}
}
// 使用方式和构造函数一样
var p1 = new Student('Li Lei',11);
p1.say();
console.log(p1);
10. 使用闭包
稳妥构造函数:闭包,不用this,不用new!安全,可靠。
function Person(name, age) {
var p={};
p.getName=function(){ return name };
p.setName=function(value){ name=value };
p.getAge=function(){ return age }
return p;
}
var p1 = Student('Li Lei',11);
var p2 = Student('Han Meimei',12);
console.log(p1.getName(), p1.getAge());
console.log(p1);
console.log(p2)
缺点:使用了闭包,容易造成内存泄漏