<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
/*工厂模式
* 存在的问题:对象识别问题
* */
console.log('工厂模式----------------');
function createObj (name,job) {
var obj=new Object();
obj.name=name;
obj.job=job;
obj.getName=function () {
// alert(this.name);
return this.name;
}
return obj;
}
var person=createObj('小王','java');
console.log(person.constructor==Object);//true
console.log(person instanceof Object);//true
console.log(person.getName());
console.log('工厂模式----------------');
/* 构造函数模式
不用写返回值,可以指明对象,但是方法的实例每次都不一样
通过new返回对象,一般构造方法的首字母大写
* */
console.log('构造器模式----------------');
function Person (name,age) {
this.name=name;
this.age=age;
this.getName=function () {
return this.name;
}
}
var person1=new Person('小青',23);
var person2=new Person('小慌',24);
console.log(person1==person2);
console.log(person1.getName==person2.getName);//false
console.log(person1.constructor==Person);//True
console.log(person1.constructor==Object);//false
//其构造器Person属于Object
console.log(person1.constructor instanceof Object);//true
//person实例属于Person和Object
console.log(person1 instanceof Person);//true
console.log(person1 instanceof Object);//true
console.log('构造器模式----------------');
//构造函数本身也是函数,可以当做普通函数使用
Person('哈哈',23);
console.log(window.getName());
console.log('构造器模式----------------');
/*原型模式
可以保证,所有的实例均来自原型, 构造函数创建对象实例,实例包含执行原型的指针[[ProtoType]],原型包含构造函数
实例.constructor=类
存在的问题:对于原型上面定义的对象,比如数组,不能单独随实例改变
* */
//先定义一个空构造函数
console.log('原型模式----------------');
function Person2 () {
}
Person2.prototype.name='初始名字';
Person2.prototype.age='默认12';
Person2.prototype.getName=function () {
return this.name;
}
Person2.prototype.hobbys=['羽毛球','篮球'];
var per1=new Person2();
var per2=new Person2();
console.log(per1==per2);//false
console.log(per1.getName==per2.getName);//true
console.log(per1.hobbys==per2.hobbys);//true
console.log(per1.constructor==Person2);//true
console.log(per1.constructor==Object);//false
//其构造器Person属于Object
console.log(per1.constructor instanceof Object);//true
//person实例属于Person和Object
console.log(per1 instanceof Person2);//true
console.log(per1 instanceof Object);//true
console.log('原型模式----------------');
//实例的属性,遵循就近原则
// hasOwnProperty:判断是否是实例自身的属性
// Object.keys:获取一个对象的可枚举的属性
// Object.getOwnPropertyNames:获取一个对象的所有属性
// in操作:判断某个属性是否属于这个对象,不区分是否来自原型对象
per2.name='per2Name';
console.log(per2.hasOwnProperty('name'));//true
console.log(per2.hasOwnProperty('age'));//false
console.log('age' in per1);//true
console.log('keys:'+Object.keys(per2));//name
console.log('keys:'+Object.keys(Person2));//
console.log('keys:'+Object.keys(Person2.prototype));//
console.log('names:'+Object.getOwnPropertyNames(per2));
console.log('names:'+Object.getOwnPropertyNames(Person2));
console.log('names:'+Object.getOwnPropertyNames(Person2.prototype));
console.log('原型模式----------------');
//简写
function Person3() {
}
Person3.prototype={
//这里需要重新生命构造函数的对象
constructor:Person3,
name:'来吧',
age:12,
getName:function () {
return this.name;
}
};
/*
混合模式:原型+构造函数
原型用来定义共享的变量和方法,函数函数用来初始化实例的属性
* */
console.log('混合模式---------------');
function Person4(name,age) {
this.name=name;
this.age=age;
//默认值
this.hobbys=['看球','游泳'];
}
Person4.prototype={
//这里需要重新生命构造函数的对象
constructor:Person4,
getName:function () {
return this.name;
}
};
var per41=new Person4('欢欢',23);
var per42=new Person4('凌达',24);
per42.hobbys.push('李白');
console.log(per41.hobbys+'------------'+per42.hobbys);
console.log(per41.hobbys==per42.hobbys);//false
console.log(per41.getName==per42.getName);
console.log(per41 instanceof Person4);
console.log('混合模式---------------');//true
/* 原型链
B的实例执行A的原型对象
存在的问题:1.还是引用类型问题,因为共享,所以每个实例的引用对象是一样的
* */
console.log('原型链----------------');
function Father (fname) {
// this.name='fname';
this.name=fname;
}
Father.prototype.getFname=function () {
return this.name+'fuc';
}
function Son () {
this.sname='sun';
}
//是Son的原型指向Father的实例
Son.prototype=new Father('FFname');
//再定义Son得方法
Son.prototype.getSonName=function () {
return this.sname+'func';
}
//测试
var son=new Son();
console.log('父类方法:'+son.name);
console.log('父类属性:'+son.getFname());
console.log('子类方法:'+son.getSonName());
console.log('子类属性:'+son.sname);
console.log(son instanceof Father);
console.log(son instanceof Son);
console.log('原型链----------------');
/*借用构造函数
可以实现:向父类传值,引用对象分别实例化
*/
console.log('----原型链--构造函数模式------------');
function Father2 (fname) {
this.name=fname;
this.colors=['red','green','black'];
this.getFname=function () {
return this.name+'fuc';
}
}
function Son2 (age,fname) {
//每次初始化Son2,会对Father2重新初始化
Father2.call(this,fname);
this.age=age;
this.getSonName=function () {
return this.age+'fuc';
}
}
var son2=new Son2(12,'fffname1');
var son3=new Son2(12,'fffname2');
son2.colors.push('blue');
//每个实例各自享有自已的引用变量,但是有些需要共享的变量确没有
console.log('color'+son2.colors);
console.log('color'+son3.colors);
//这里想让name共享,但是构造函数式实现不了的
console.log('name:'+son2.name);
console.log('name:'+son3.name);
console.log('父类方法:'+son2.name);
console.log('父类属性:'+son2.getFname());
console.log('子类方法:'+son2.getSonName());
console.log('子类属性:'+son2.age);
console.log(son2 instanceof Father2);//false
console.log(son2 instanceof Son2);//true
console.log('----原型链--构造函数模式------------');
/*组合模式
原型链:用来定义共享的属性和方法
构造函数:用来定义不需要共享的属性对象
* */
console.log('----原型链+构造函数组合模式--推荐----------');
function Father3 (fname) {
this.name=fname;
this.colors=['red'];
}
//方法共享
Father3.prototype.getFname=function () {
return this.name+'fuc';
}
//继承属性
function Son3 (age,fname) {
Father3.call(this,fname);
this.age=age;
}
//继承方法 这里虽然可以给Father3传参,但是没必要
Son3.prototype=new Father3();
// Son3.prototype.constructor=Father3;
Son3.prototype.getSonName=function () {
return this.age+'func';
}
//测试
var s1=new Son3(11,'fatherName');
var s2=new Son3(13,'ffffffffff');
s1.colors.push('blue');
//每个实例各自享有自已的引用变量,但是有些需要共享的变量确没有
console.log('color:'+s1.colors);
console.log('color:'+s2.colors);
console.log(s1.getFname==s2.getFname);//true
console.log('父类方法:'+s1.name);
console.log('父类属性:'+s1.getFname());
console.log('子类方法:'+s1.getSonName());
console.log('子类属性:'+s1.age);
console.log(s1 instanceof Father3);//true
console.log(s1 instanceof Son3);//true
console.log('----原型链+构造函数组合模式--推荐----------');
</script>
<body>
</body>
</html>
原型学习
最新推荐文章于 2023-10-16 09:19:04 发布