構造函甚至沒必要返回這個新建立的對象,構造函數會自動建立對象,而後將構造函數看成爲這個對象的方法來調用一次,最後返回這個新對象。javascript
當使用instanceof運算符來檢測對象是否屬於某個類時會用到構造函數java
r instanceof Range//若是r繼承自range.prototype,則返回trueecmascript
實際上instranceof運算符並不檢查r是否由range構造函數初始化而來,而是檢查r是否繼承自range.prototype.函數
若是o繼承自c.prototype,則表達式o instanceof c值爲true,這裏的繼承能夠不是直接繼承,若是o所繼承的對象繼承自另外一對象,後一個對象繼承自c.prototype,這個表達式的運算結果也是true。this
若是你檢測對象的原型鏈上是否存在某個特定的原型對象,有沒有不使用構造函數做爲中介的方法麼?答案是確定的,能夠使用isPrototypeOf()方法。spa
constructor 另外一種識別對象是否屬於某個類的方法是constructor屬性。由於構造函數是類的公共標識符,因此最直接的方法就是使用constructor屬性。prototype
function typeAndValue(x){ if(x==null)return ""; switch(x.constructor){ case Number:return "Nuber: "+x; case String: return "String:'"+x+"'"; case Date: return "Date:"+x; case RegExp: return "RegExp"+x; } } console.log(typeAndValue(1));//Nuber: 1 console.log(typeAndValue("1"));//String:'1' console.log(typeAndValue(new Date()));//Date:Tue Dec 22 2015 19:42:15 GMT+0800 (中國標準時間)
任何javascript函數均可以用做構造函數,而且調用構造函數是須要用到一個prototype屬性的。所以,每一個javascript函數(除了ecmascript 5中的Function.bind方法返回的函數以外)都自動擁有一個prototype屬性。這個屬性的值是一個對象。這個對象包含惟一一個不可枚舉屬性constructor。constructor屬性的值是一個函數對象。code
function f(){}; var p=f.prototype; var c=p.constructor; console.log(c);//function f(){} console.log(p);//f {} console.log(c===f);//true
對任意函數F.prototype.constructor==F;對象
能夠看到構造函數的原型中存在預先定義好的constructor屬性,這意味這對象一般繼承的constructor均指代它們的構造函數,因爲構造函數是類的公共標識,所以這個constructor屬性爲對象提供哦了類blog
var o=new F();
o.constructor===F;//true
range類使用它自身的一個新對象重寫了預約義的rang.prototype對象,這個新定義的原型對象不含有constructor屬性。所以range類的實例也不含有constructor屬性,咱們能夠經過補救來修正這個問題,顯示的給原型添加一個構造函數:
function Range(){ this.x=1; this.y=2; }; Range.prototype={ constructor:Range }; var p=new Range(); console.log(p.constructor);
另外一種常見的解決方法是使用預約義的原型對象,預約義的原型對象包含construtor屬性,而後依次給原型對象添加方法
類的擴充
String.prototype.trim=String.prototype.trim||function(){ if(!this)return this; return this.replace(/^\s+|\s+$/g,""); }; console.log(" sdf ".trim());//sdf Function.prototype.getName=function(){ return this.Name|| this.toString().match(/function\s*([^()]*)\(/)[1]; }; function test(){ } console.log(test.getName());//test
在javascipt中並不是全部的對象都包含constructor屬性。在每一個新建立的函數原型上默認會有constructor屬性,但咱們經常忽略原型上的constructor屬性。好比下面的實例就沒有constructor屬性
function F(){ } F.prototype={}; var o=new F(); function inhernit(o){ if(o==null) return null; function f(){}; f.prototype=o; return new f(); } var t=inhernit(o);
function type(o){ var t,c, n;//type,class ,name //處理null值得特殊情形 if(o===null) return "null"; if(o!==o) return "nan"; if((t=typeof o)!=="object"){ return t; } if((c=classof(o))!=="Object"){ return c; } if(o.constructor&&typeof o.constructor==="function"&&(n=o.constructor.getName())){ return n; } return "Object"; } function classof(o){ return Object.prototype.toString.call(o).slice(8,-1); } Function.prototype.getName=function(){ if("name" in this) return this.name; return this.name=this.toString().math(/function\s*([^(]*)\(/)[1]; }; function test(){}; var p=new test(); console.log(type(p));
並非全部的對象都具備constructor屬性,此外,並非全部的函數都有名字,若是使用不帶名字的函數定義表達式定義一個構造函數,那麼getName方法則返回空字符串。
var complex=function(x,y){};//這個構造函數沒有名字 var range=function range(){};//這個構造函數有名字