做用是執行構造函數,返回實例對象
function F() { this.name = "object" } var obj = new F();
上面例子是自定義一個構造函數,其最大的特色就是首字母大寫,用new執行構造函數;
其中this,在new的執行下,表明了實例化後的對象,這個obj也就有name屬性
注意點:若是不用new執行構造函數,那麼this指向的是全局window數組
function F() { this.name = "object" } var obj = F(); console.log(obj); //undefined console.log(name); //object
有兩種方式能夠避免:app
function F() { this.name = "object" } F(); //TypeError: Cannot set property 'name' of undefined
function F() { if(!(this instanceof F)){ return new F(); } this.name = "object" } F();
function F() { if(!new.target){ return new F(); } this.name = "object" } F();
簡單來講:不加new執行,this就是window;加了new執行,那麼this = Object.create(F.prototype),構建一個空對象,繼承下F的原型函數
return的內容不是對象,則忽視,返回的時this對象this
function F() { this.name = "object" reutrn 123; } var obj = F(); //{name : "object"}
return的內容是對象時,則返回return的對象,(null除外)prototype
function F() { this.name = "object" reutrn {a : 123}; } var obj = F(); //{a : 123}
前提是使用了new來執行構造函數
利用上述原理咱們能夠簡單模擬一個new的函數code
function _new(constructor, params) { //將arguments對象轉爲數組 var args = [].slice.call(arguments); //1.取出參數中的構造函數,2.過濾args,剩下對構造函數有用的實參 var constructor = args.shift(); //構建空對象,並繼承構造函數的原型 var context = Object.create(constructor.prototype); //1.借用構造函數,將context空對象賦給this,2.並args實參與構造函數參數一一對應對其賦值,3.造成完整的this對象 var result = constructor.apply(context, args); //這個是處理return返回對象時的狀況 return (typeof result === "object" && result != null) ? result : context; } function P(n) { var a = 1; this.b = n; //return null; } var p = _new(P,123); console.log(p);