最近開始學習js,在看到書上的一個例子時,引發了我的一系列思考:
書上例子:
function Person(name,age,job){
var o =new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(this.name);
};
return o;
}
var friend=new Person("Nicholas",29,"Software Engineer");
friend.sayName();
Person函數創建了一個對象,並以相應的屬性和方法初始化該對象,然后又返回了這個對象,除了使用new操作符且把使用的包裝函數叫做構造函數之外,這個模式跟工廠模式是一模一樣的。
注意:構造函數在不返回值的情況下,默認返回新對象實例。
看到這里,我就將上面的例子的new關鍵字去掉,發現和原來結果一樣。
而后,我寫了一下幾個例子,進行比較:
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=function(){
alert(this.name);
};
}
//var person=new Person("張三",20); //此處為 構造對象,構造對象的話,返回的新對象是由解析器自己生成的。
var person=Person("張三",20); //報錯 person undefined 此處為普通函數調用,又沒有給定返回值,出錯。
person.sayName();
得出結論:使用new關鍵字是將函數當作構造函數調用,即為構造對象,若沒有人為的重寫調用構造函數時返回的值,那么返回的對象是由解析器自己生成的。不使用new關鍵字調用函數,即為普通函數調用。
隨即想到若是函數返回值是function型的呢?
例子:
function Test() {
this.name = 'Test';
return function() { return true; }
}
//var test = Test();// test function() { return true; }
var test01 = new Test();// 構造對象
var test02=Test();//函數調用
alert(test01==test02);//false 雖然瀏覽器運行結果一樣,但是比較結果還是false,因為 Javascript 對於 Object 和 Function 的比較是基於引用的。
瀏覽器運行監視結果發現:
最后我將返回值改成String類型:
function Test() {
this.name = 'Test';
return "Test" ;
}
//var test = Test();// test function() { return true; }
var test01 = new Test();
var test02=Test();
alert(test01==test02);//false
瀏覽器下運行監視結果:
最后得出一個猜測:
如果函數返回值為常規意義上的值類型(Number、String、Boolean)時,new 函數將會返回一個該函數的實例對象,而如果函數返回一個引用類型(Object、Array、Function),雖然new函數與直接調用函數產生的結果等同,但是是兩個不同的過程,一個是構造對象、一個是函數調用。
通過在 Test函數中返回不同類型的值進行測試,可以證實這一點。
-END-