javascript中初始化建構函式時new所起的作用

慕斯不想說話發表於2019-04-05

先看一下如下例項程式碼

function Person(name,age){
	this.name=name;
	this.age=age;
}
Person.prototype.say=function(){
	console.log("姓名:"+this.name+",年齡:"+this.age);				
}
var p1=new Person("黎明",30);
console.log(p1.name);//黎明
p1.say();//姓名:黎明,年齡:30
複製程式碼

1、new在這個過程中執行了以下三個步驟

1、建立一個空物件;
2、然後讓這個空物件的__proto__指向函式的原型prototype,繼承了該函式的原型。
3、呼叫call方法,將這個空物件物件作為函式的this傳進去,並且最後隱式的返回這個空物件 。

2、呼叫建構函式使用new關鍵字的情況

var p1=new Person("黎明",30)這句程式碼的內部程式碼執行如下:

 new Person("黎明",30)={
     var obj  = {};//建立一個空物件 
	 obj.__proto__ = Person.prototype;   
	 Person.call(obj,"黎明",30);
	 return obj;
 }
複製程式碼

  分析:所以new在這個過程中的作用是,使p1繼承了Person的name和age屬性,使p1的原型指向了Person的原型,使得p1擁有了Person的全部例項屬性和原型物件,因此p1具有了name和age屬性以及say方法。new Person("黎明",30)返回的是如下所示的物件

javascript中初始化建構函式時new所起的作用

3、呼叫建構函式不使用new關鍵字的情況

 var p2=Person("李明",24);
 console.log(p2.name);//Cannot read property 'age' of undefined
複製程式碼

  分析:此時相當於只是呼叫了Person("李明",24)的這樣一個普通方法,並不是呼叫Person建構函式建立一個新的例項物件,並且該方法沒有返回值,所以呼叫Person("李明",24)返回的是預設值undefined。因此P2也沒有name和age屬性。

var p2=Person("李明",24)
p1.say.call(p2);//"姓名:李明,年齡:24
複製程式碼

為什麼這句程式碼會有輸出呢?原因如下

1、var p2=Person("李明",24);在Person構造方法中的this表示的是window,所以就有;

        window.name="李明";
        window.age=24;
複製程式碼

2、p1.say.call(p2)中的p2表示是呼叫Person("李明",24)建構函式後的返回值,但是該建構函式沒有返回值,因此p2=undefined,根據call方法的定義,所以在say()方法中的this表示window。

4、呼叫建構函式時,在內部有retun語句的情況

 function Person(name,age){
	this.name=name;
	this.age=age;
	return name;
}
 var p1=new Person("黎明",23);
 console.log(p1);//{name: "黎明",age:23}
複製程式碼

 function Person(name,age){
	this.name=name;
	this.age=age;
	return {};
}
 var p1=new Person("黎明",23);
 console.log(p1);//{}
複製程式碼

  原因分析:建構函式不需要顯示的返回值。使用new來建立物件(呼叫建構函式)時,如果return返回的是非物件(數字、字串、布林型別等)會忽略返回值;如果return的是物件,則返回該物件(注:若return null也會忽略返回值)。

相關文章