javascript 面向对象编程之创建对象详解编程语言
这部分属于JavaScript的面向对象编程,探讨如何更好的创建对象。在java中有类的概念,用new就可以创建对象, 但JavaScript没有类,所以也就无法创建某一类对象,但是可以利用一些技巧达到创建对象的目的。以下所说的各种模式是循序渐进的,如果理解了,记住各种方式也不是难事。
最原始的方式var person = new Object(); person.name="jun"; person.age=12; person.sayName=function (){ console.log(this.name);
以上是最原始、最简单的创建对象的方法,但是它有一个缺点,就是代码重复,如果再创建一个person,就需要再次敲上述语句,这就是典型的代码重复,那直接的解决方案就是将上述语句放在一个方法中,这就是工厂模式了。
//工厂模式,缺点无法判断类型 function createPerson(name,age){ var a = new Object(); a.name=name; a.age=age; a.sayName=function (){ console.log(this.name); return a; var p1 = createPerson("jun",20); var p2 = createPerson("chun",18); console.log(p1 instanceof Object);//true console.log(p2 instanceof Object);//true
工厂模式实现了代码封装,它的缺点是不能判断对象类型,创建的对象都是Object类型,为了解决这个问题,就需要构造函数模式了。
构造函数模式//构造函数模式 function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ console.log(this.name);
console.log(p4 instanceof Person);//true console.log(p3.sayName==p4.sayName);//false
构造函数模式创建的对象可以判断出类型,它的缺点是每个实例都要创建一个新的function。我们都知道在js中函数也是对象,上述代码中this.sayName=function(){} 就等同于this.sayName=new Function("") 所以每个实例都会创建一个新的函数,这就造成了实例之间的函数不相等。为了fix这个问题,自然而然的想到将函数拿到构造函数之外。
function Person(name,age){ this.name=name; this.age=age; this.sayName=sayName; function sayName(){ console.log(this.name); var p3 = new Person("jack",40); var p4 = new Person("jordan",50); console.log(p3.sayName==p4.sayName);//true
这样函数相等的目的达到了,但是可访问性增大,污染了全局环境,破坏了封装性,为了修正这个问题就想到将函数放在原型上,所有的实例就可以共享了。
我们知道函数都有一个prototype属性指向它的原型,所有的实例都可以共享原型的属性、方法。将方法定义在函数的原型上,就能避免函数的重复创建。
function Person(){
console.log(p3.sayName==p4.sayName);//true
函数共享了,但是实例属性也共享了。到这里读者可以思考了,构造函数模式分离了属性、函数,原型模式共享了属性、函数,如果能结合一下构造函数分离属性,原型模式共享函数该多好,这就是原型+构造函数模式。
原型+构造函数混合模式function Person(name,age){ this.name=name; this.age=age; Person.prototype.sayName=function (){ console.log(this.name);
console.log(p3.sayName==p4.sayName);//true
这个模式还是有个缺点!^_^ 函数放在外边破坏了封装性,所以就有了
function Person(name,age){ this.name=name; this.age=age; if(typeof this.sayName!="function"){ Person.prototype.sayName=function (){ console.log(this.name); }
这种事业界内最推崇、最成熟的创建对象方式了。
寄生构造函数模式修改原型以扩展方法虽然方便但也带来了缺点,比如String没有startsWith方法,我们会通过扩展原型来实现
String.prototype.startsWith=function(){ //do something }
但是你有没有想到,未来的js版本可能会实现这个方法,到那时js版本带的方法就跟扩展的方法冲突了,为了解决这个问题,就产生了寄生构造函数模式。
比如我们想创建一个新的Array,它有原生Array没有的方法
function SpecialArray(){ var x = new Array(); x.push.apply(x,arguments); x.pipedStr=function(){ console.log(x.join("|")); return x; var xx = new SpecialArray("a","b","c"); xx.pipedStr();
我们可以看到寄生构造函数模式跟工厂模式基本一样,为了使用起来像创建新类型一样,用new创建对象。
稳妥构造函数模式有时我们不像让外界修改对象的值,怎么实现呢?只提供访问的方法,不提供修改的方法就可以了!因为值不能改变,是稳定的、可靠的,所以就叫稳妥方式。
function Person(name){ var x = new Object(); x.sayName=function(){ console.log(name); return x; var y = Person("jun"); y.sayName();
注意,这里并没有使用new。
以上所有的模式除了最后两种,都可以一步步推倒出来,循序渐进的演变过来的,所以,不用死记硬背。
JavaScript高级程序设计(第2版)
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/20293.html
cjavaxml相关文章
- 【说站】javascript中call函数的原理
- 轻松学习 JavaScript——第 6 部分:JavaScript 箭头函数详解编程语言
- JavaScript 与 Java、PHP 的比较详解编程语言
- 点击验证码重新加载验证码图片JavaScript代码详解编程语言
- JavaScript常用方法函数收集详解编程语言
- JavaScript判断浏览器版本详解编程语言
- Javascript计时器的实现详解编程语言
- JavaScript去除数组中重复字符串详解编程语言
- JavaScript实现限时抢购实例详解编程语言
- 实现千元分隔符javascript代码详解编程语言
- 使用Javascript设置,获取和删除cookie详解编程语言
- JavaScript将首字母转成大写详解编程语言
- JavaScript控制输入框只能输入非负正整数详解编程语言
- JavaScript学习总结(十七)——Javascript原型链的原理详解编程语言
- JavaScript学习总结(十五)——Function类详解编程语言
- HTML/CSS/JavaScript学习笔记持续更新详解编程语言
- JavaScript递归函数解“汉诺塔”详解编程语言
- Errors running builder ‘JavaScript Validator’ on project ‘……’.详解编程语言
- JavaScript去除前后空格详解编程语言
- javascript实现文字隐藏详解编程语言
- 谈谈javascript种的数组,和数组相关操作详解编程语言
- java和JAVASCRIPT语言的本性区别详解编程语言
- javascript和jQuery的类型判断详解编程语言
- javascript获取时间戳的方法详解编程语言