按照javascript的设计理念,new关键字本就不该出现的。按照经典面向对象的思维,new就是创建一个类的对象。
但是javascript又没有类这一概念,所以显得晦涩难懂。一般来说,我们会这样使用new来创建一个对象。
var Mammal = function(name){ this.name = name; } var mammal = new Mammal("monkey"); alert(mammal.name);
那么new到底做了些什么事情呢?道格拉斯在《javascript精粹》里面讲到,使用new关键字去创建一个对象时,
如果把new当作一个函数来实现,它大概是这种实现方式:
Object.beget = function(o){ var F = function(){}; F.prototype = o; return new F; } Function.method = function(funcName,func){ Function.prototype[funcName]=func; } Function.method("new", function(){ var that = Object.beget(this.prototype); var other = this.apply(that,arguments); return (typeof other === ‘object‘ && other) || that }); var Mammal = function(name){ this.name = name; } Mammal.prototype.get_name = function(){ return this.name; } var mammal = Mammal.new("monkey"); alert(mammal.get_name());
这段代码包括后续紧跟着的例子,我看书的时候是看了好一阵。这本书唯一不太好的是,每个例子和前面都是有关联的。
像这个例子,前两个函数本来是没有的,它们出现在前几章的某个例子中,如果不是一口气看完的,很容易忘记。这段代码
的意思大概是说,用关键字new去创建一个函数A(准确的说是构造器)的对象的时候,首先,它会去以A的原型对象去创建
一个新对象that,从而这个新对象that能得到原型对象的所有属性和方法。然后利用apply函数去调用A,并且将A的this绑定
在that上,如果调用A的返回值other是一个object,则返回这个other;否则返回刚才创建的that。
不过,在以A的原型对象去创建新对象that时,它调用了一个自定义的方法:Object.beget 。它是道格拉斯在书中提出来,
并且建议在创建对象时使用,而不去直接使用new关键字,虽然它的实现也用到了new关键字。所以我对道格拉斯在解释new
如何实现时却又调用这个包含new操作的方法,不是很理解,这不是无穷递归,讲不清楚了么?当然,在Beget调用new F时,
F是十分简单的,除了一个prototype以外什么都没有。所以new的实现方式基本也能够理解。
好在后来我找到了这篇文章,http://handyxuefeng.blog.163.com/blog/static/454521722011519104115831/
基本上讲的十分清楚了,还贴心的配了图,有兴趣的可以去看看~~