1、js 创建对象的方式
参考链接:https://www.cnblogs.com/juggd…
(1)new 操作符 + object 创建对象
var person = new Object();
person.name = 'zhangsan'
person.setName = function(){alert(this.name)
}
(2)字面式创建对象
var person = {
name: 'zhangsan',
setName: function(){alert(this.name)
}
}
以上两种方法在使用同一接口创建多个对象时,会产生大量重复代码。可以使用工厂模式。
(3)工厂模式
function createPerson(name, age){var o = new Object();
o.name = name;
o.age = age;
o.setName = function(){alert(this.name)
}
return o;
}
工厂模式解决了重复实例化多个对象的问题,但没有解决对象识别的问题(但是工厂模式却无从识别对象的类型,因为全部都是 Object,不像 Date、Array 等,本例中,得到的都是 o 对象,对象的类型都是 Object,因此出现了构造函数模式)
(4)构造函数模式
function Person(name, age){
this.name = name;
this.age = age;
this.setName = function(){alert(this.name)
}
}
var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
var person2 = new Person("lisi",21,["lida","lier","lisi"]);
console.log(person1 instanceof Object); //true
console.log(person1 instanceof Person); //true
console.log(person2 instanceof Object); //true
console.log(person2 instanceof Person); //true
console.log(person1.constructor); //constructor 属性返回对创建此对象的数组、函数的引用
对比工厂模式有以下不同之处:
1、没有显式地创建对象
2、直接将属性和方法赋给了 this 对象
3、没有 return 语句
以此方法调用构造函数步骤 {
1、创建一个新对象
2、将构造函数的作用域赋给新对象(将 this 指向这个新对象)
3、执行构造函数代码(为这个新对象添加属性)
4、返回新对象
}
可以看出,构造函数知道自己从哪里来(通过 instanceof 可以看出其既是 Object 的实例,又是 Person 的实例)
构造函数也有其缺陷,每个实例都包含不同的 Function 实例(构造函数内的方法在做同一件事,但是实例化后却产生了不同的对象,方法是函数,函数也是对象),
因此产生了原型模式
(5) 原型模式
function Person(){}
Person.prototype.name = 'lisi'
Person.prototype.age = 21
var person1 = new Person(); // 创建一个实例 person1
console.log(person1.name); //lisi
var person2 = new Person(); // 创建实例 person2
person2.name = "wangwu";
person2.family = ["lida","lier","lisi"];
console.log(person2);
原型模式的好处是所有对象实例共享它的属性和方法(即所谓的共有属性),此外还可以如代码那样设置实例自己的属性(方法)(即所谓的私有属性)
(6)混合模式(构造函数模式 + 原型模式)
构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype = {
constructor: Person, // 每个函数都有 prototype 属性,指向该函数原型对象,原型对象都有 constructor 属性,这是一个指向 prototype 属性所在函数的指针
say: function(){alert(this.name);
}
}
var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
console.log(person1);
var person2 = new Person("wangwu",21,["lida","lier","lisi"]);
console.log(person2);
可以看出,混合模式共享着对相同方法的引用,又保证了每个实例有自己的私有属性。最大限度的节省了内存
(7)Object.create
new Object() 通过构造函数来创建对象, 添加的属性是在自身实例下。
Object.create() es6 创建对象的另一种方式,可以理解为继承一个对象, 添加的属性是在原型下。
const person = {
isHuman: false,
printIntroduction: function () {console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
};
const me = Object.create(person);
me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten
me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"