admin管理员组文章数量:1794759
工厂函数和构造函数的区别
工厂函数和构造函数的区别
下面是给出的两个都是实现 “定义使用值的范围” 的函数, 第一个工厂函数(工厂模式)用以创建并初始化类的实例,而且给出了一个表示“值的范围”的类定义了原型对象;第二个是使用构造函数代替工厂函数来实现相同功能的代码段 。
下面是“inherit()通用写法
function inherit(d){ if(d == null) throw TypeError(); //d 是一个对象,但不能是null; if(Object.create) //如果Object.create()存在 return Object.create(d); //直接使用d var t = typeof d; //否则进行进一步检测 if(t !== 'object' && t !== 'function') throw TypeError(); function f(){}; //定义一个空的构造函数 f.prototype = d; //将其原型属性设置为 d; return new f(); //使用f()创建d的继承对象 }下面是“工厂函数”的一段代码
function range(from,to){ //使用inherit()函数创建对象,这个对象继承自在下面定义的原型对象 //原型对象作为函数的一个属性存储,并定义所有“范围对象”所共享的方法。 var r = inherit(range.methods); //存储新的“范围对象”的起始位置和结束位置 //这两个属性是不可继承的,每个对象都拥有唯一的属性。 r.from = from; r.to =to; return r;//返回这个新建立的对象 } //原型对象定义方法,这些方法为每个范围对象所继承 range.methods = { includes: function(x){ //如果x在范围内,返回 true 否则返回false if(this.from <= x && x <= this.to){ return x; } return x; }, foreach: function(f){ //对范围内的每个整数都调用一次 f for(var x = Math.ceil(this.from);x <= this.to; x++) f(x); }, toString: function(){ return "("+this.from +".."+ this.to + ")"; } }; var r = range(1,4); r.foreach(console.log); // 输出 1 2 3 4 console.log(r.toString()); // 输出(1..4) r.includes(2); //返回2这段代码是用来定义一个工厂方法 range(),用来创建新的范围对象。 rang()函数定义了一个属性range.methods,用来快捷地存放定义类的原型对象。把原型对象挂在函数上不是惯用做法。而且range()函数给每个范围对象都定义了from 和to 属性,用来定义范围的起始位置和结束位置,这两个属性是非共享的,也不可继承。
使用构造函数代替“工厂函数”
function Range(from, to){ //构造函数初始化 this.from = from; this.to = to; } Range.prototype = { //所有范围对象都继承自这个对象 includes: function(x){ return this.from <= x && this.to >= x; }, foreach: function(f){ for(var x = Math.ceil(this.from); x <= this.to; x++) f(x) }, toString: function(x){ return "(" + this.from + ".." + this.to + ')'; } }; var t = range(1,4); t.foreach(console.log); // 输出 1 2 3 4 console.log(t.toString());// 输出 (1..4); t.includes(3); // 输出 3上述两个函数的不同之处
通过new关键字调用,不必调用inherit() | 不需要使用new,但是需要调用inherit() |
使用构造函数调用创建对象 | 调用普通函数创建对象 |
通过this关键字获取这个新对象,不必返回新对象。 | 函数需要返回新建立的对象 |
构造函数会自动创建对象,然后将构造函数作为这个对象的方法来调用一次,最后返回这个新对象 | 函数里面的属性是不可继承的,每个对象的属性都拥有唯一的属性 |
原型对象的命名Range.prototype是强制的命名,对该函数的调用会自动使用Range.prototype作为新Range对象的原型 | 原型是range.methods,这种命名方式方便且具有很好的语义,担又过于随意。 |
两者的范围方法定义和调用方式是完全一样的 |
使用关键字new来调用构造函数会自动创建一个新的对象,因此构造函数本身只需初始化这个新对象的状态即可。 调用构造函数的一个重要的特征: 构造函数的prototype属性被用作新对象的原型。这意味着通过一个构造函数创建的所有对象都继承自一个相同的对象,因此他们都是同一个类的成员。
3、构造函数的内部原理、 1、在函数体最前面隐式的加上this = {} 2、执行this.xxx = xxx; 3、隐式的返回 this4、在用new操作符创造实例时,会经历如下4个阶段:
版权声明:本文标题:工厂函数和构造函数的区别 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686491049a73453.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论