创建对象
1.工厂模式
//工厂模式,可以解决创建多个相似对象,无法识别对象是哪个类型
function createPerson(name,age,job) {
var o = new Object();//显示的创建对象
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(o.name);
}
return o; //返回对象才能被外部引用
}
var person = createPerson("工厂",12,"doctor");
person.sayName();
2.构造函数模式
//构造函数类型
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
}
}
//调用方式
//1.当构造函数来调用
var person1 = new Person("构造1",12,"doctor");//引用时new 创建对象,this指向了新对象
var person2 = new Person("构造person2",12,"doctor");//引用时new 创建对象,this指向了新对象
console.log(person1 instanceof Person);//true
//2.普通函数调用
Person("构造2",12,"doctor");//添加到window
Person("构造4",12,"doctor");//添加到window
window.sayName();//构造4
//3.在另一个函数的作用于中调用
var b = new Object();
Person.call(b,"构造3",12,"doctor");
b.sayName();//构造3
console.log(person1.sayName== person2.sayName ) //false 会创建两个做同样任务的函数实例
//改进的构造函数类型
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName =sayName; //将函数定义成全局函数,但该函数只能某个特定的对象来调用
}
function sayName(){
console.log(this.name);
}
3.原型模式
//原型模式
function Original() {
}
Original.prototype.name = "Tom";
Original.prototype.age = 20;
Original.prototype.job = "Doctor";
Original.prototype.sayName = function () {
console.log(this.name);
};
var or1 = new Original();
var or2 = new Original();
or1.name = "JOiny"; //重新定义实例属性,但不改变原型属性
console.log(or1.name);//JOiny 来自实例
console.log(or1.hasOwnProperty("name")); //true hasOwnProperty 是否有实例属性
console.log("name" in or1); //true 给定属性是否在对象中,,实例和原型中皆可
console.log(or2.name);//Tom 来自原型
delete or1.name;//delete 删除实例属性
console.log(or1.name);//
//原型模式2 重写了默认的prototype对象,prototype 不在指向Original2 而是指向Object对象
function Original2(){
}
Original2.prototype = {
constructor : Person,
name : "Nicholas",
age : 29,
job: "Software Engineer",
sayName : function () {
console.log(this.name);
}
};
var friend = new Original2();
console.log(friend instanceof Object); //true
console.log(friend instanceof Original2); //true
console.log(friend.constructor == Original2); //false
console.log(friend.constructor == Object); //true
Original2.prototype.sayHi = function(){
console.log("hi");
};
friend.sayHi(); //"hi" ?works!
//实例中的指针仅指向原型,不指向构造函数,即重写的原型对象
function Student(){
}
var friend = new Student();
Student.prototype = {
constructor: Student,
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
alert(this.name);
}
};
// friend.sayName(); //error
console.log("------------------------------------------eg");
console.log(typeof Array.prototype.sort); //"function"
console.log(typeof String.prototype.substring); //"function"
//通过原型模式给String 对象定义新的方法
String.prototype.startsWith = function (text) {
return this.indexOf(text) == 0;
};
var msg = "Hello world!";
console.log(msg.startsWith("Hello")); //true
//原型对象的问题
console.log("------------------------------------------原型对象的问题");
function Tea(){
}
Tea.prototype = {
constructor: Tea,
name : "Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby", "Court"],
sayName : function () {
console.log(this.name);
}
};
var tea1 = new Tea();
var tea2 = new Tea();
tea1.friends.push("Van");
console.log(tea1.friends); //"Shelby,Court,Van"
console.log(tea2.friends); //"Shelby,Court,Van"
console.log(tea1.friends === tea2.friends); //true
4.组合使用原型模式和构造函数模式 (常见的方式)
//组合使用原型模式和构造函数模式
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Tom","Lily"];
}
Person.prototype = {
constructor : Person,
sayName:function () {
console.log(this.name);
}
}
var p1 = new Person("zz",21,'teacher');
var p2 = new Person("cc",21,'student');
p1.friends.push("Lucy");
console.log(p1.friends);
p1.sayName();
console.log(p2.friends);
p2.sayName();
5.动态原型模式
//动态原型模式
function Person(name, age, job){
//properties
this.name = name;
this.age = age;
this.job = job
//methods
if (typeof this.sayName != "function"){
Person.prototype.sayName = function(){
console.log(this.name);
};
}
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName()
6.寄生构造函数
//寄生构造函数,与工厂模式语法相同,在不改变原有的引用类型下返回新的值
function specArray() {
var newArr = new Array();
//赋值
newArr.push.apply(newArr,arguments);
newArr.toSpecString = function () {
return this.join("|");
}
return newArr;
}
var arr = new specArray("Gelei","Nazi")
var specArr = arr.toSpecString();
console.log(specArr); //Gelei|Nazi
7.稳妥构造函数模式