首页 > 代码库 > JS面向对象笔记
JS面向对象笔记
1、工厂模式
function CreatePerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.showName = function(){ alert(this.name); } return o; } var person1 = CreatePerson(‘王五‘,‘25‘,‘Coder‘);
可以按照上述方式批量生成包含所有必要信息的CreatePerson对象 并且可以反复调用
缺点是 无法解决对象识别的问题
2、构造函数模式
// 构造函数模式 function CreatePerson(name,age,job){ this.name = name; this.age = age; this.job = job; this.showName = function(){ alert(this.name); } } var person1 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘); var person2 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘);
此时 有如下几个优点
- 没有工厂模式下的显式的创建对象
- 直接将属性和方法赋给了this对象
- 并且没有return语句等缺点
缺点:
- 必须用new操作符来创建一个新的实例
- 方法不公用
pesron1和pesron2是两个不同的实例 指向不同地址 所以不相等
console.log( person1 == person2); //false
但是两个对象都拥有constructor属性 并且该属性指向CreatePerson
1 console.log( person1.constructor == CreatePerson); //ture 2 console.log( person1.constructor == person2.constructor); //true
本来constructor属性是用来标识对象类型的,但是现在有更多的标识对象类型的方法 instanceof
1 console.log( person1 instanceof Object ); //true 2 console.log( person1 instanceof CreatePerson ); //true
方法不公用
1 console.log( person1.showName == person2.showName); //false
3、原型模式
每一个函数都有prototype原型属性 这个属性是一个指针 指向一个对象 可以用这个原型来实现方法的公用
1 // 原型模式 2 function CreatePerson(name,age,job){ 3 this.name = name; 4 this.age = age; 5 this.job = job; 6 } 7 8 CreatePerson.prototype.showName = function(){ 9 alert(this.name); 10 } 11 12 var person1 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘); 13 var person2 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘);
此时的方法公用
1 console.log(person1.showName == person2.showName); //true
未完待续。。。。。。。。。。。。。。。
新建一个名为Person的构造函数
function Person(name,sex){ this.name = name; this.sex = sex; } Person.prototype.showName = function(){ console.log(this.name); } Person.prototype.showSex = function(){ console.log(this.sex); } // 新建一个Person构造函数的实例 var person1 = new Person(‘张三‘,‘男‘); person1.showName(); //张三 person1.showSex(); //男
再新建一个名为Worker的构造函数
通过call()或者apply()来实现继承父级的属性
常见的错误继承方法
function Worker(name,sex,job){ //构造函数伪装 将Worker构造函数中this传到Person中 //继承父级的属性 call来改变作用域 也可以使用apply // //第一种call 必须要将第二个参数全部列举出来 Person.call(this,name,sex); //第二种apply 参数为数组 // Person.apply(this,[name,sex]); this.job = job; } // 原型链 继承父级的原型方法 // 第一种 浅复制 指向同一地址 对Worker的方法会影响到父级Person 不推荐使用 Worker.prototype = Person.prototype; Worker.prototype.showJob = function(){ console.log(this.job); } var worker1 = new Worker(‘李四‘,‘女‘,‘UI设计师‘); worker1.showName(); //李四 worker1.showSex(); //女 worker1.showJob(); //UI设计师
此时
// 问题出在父级也拥有子级的showJob方法 console.log(Person.prototype); //Object { //showJob: () //showName: () //showSex: () //__proto__: Object //}
这是由于前复制
Worker.prototype = Person.prototype;
父级和子级指向同一对象的地址 对子级的修改同样会影响到父级 为了避免这样的情况得new一个新对象来开辟新的地址来存放对象
// 第二种 寄生构造函数模式 Worker.prototype = new Person(); // 或者 通过循环的方式 for( var i in Person.prototype){ Worker.prototype[i] = Person.prototype[i]; }
此时
console.log(Person.prototype);
没有showJob的方法
instanceof ...的实例
console.log(Person instanceof Object) //true console.log(person1 instanceof Object) //true console.log(person1 instanceof Person) //true console.log(person1 instanceof Worker) //false console.log(worker1 instanceof Person) //true
JS面向对象笔记
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。