第一種情況(無返回值)
function Person(name){
this.name=name;
this.sayName=function(){
console.log(this.name);
};
}
const a = Person('張三');//執(zhí)行了Person('張三'),但是沒有返回值
//a=執(zhí)行后的Person('張三')=無返回值=undefined
const b = new Person('李四');//新建了一個Person('李四')對象
a.sayName();//報錯
b.sayName();//李四
window.sayName();//張三
為什么會出現(xiàn)這種情況食零?
- 如果聲明時沒有new滑废,其實就是簡單的函數(shù)調用并賦值蝗肪,如果函數(shù)也沒有返回值,那么函數(shù)調用并沒有什么意義蠕趁,也就是說聲明的a=undefined薛闪,然后執(zhí)行了Person('張三'),但是是屬于window對象俺陋,所以執(zhí)行window.sayName()能輸出張三
- 如果聲明時有new豁延,具體發(fā)生如下
1.創(chuàng)建一個繼承自構造函數(shù)原型的新對象,也就是創(chuàng)建一個新的內存空間腊状,然后讓該內存空間的__ proto__指向構造函數(shù)的prototype诱咏。(繼承構造函數(shù)的原型鏈)
2.將構造函數(shù)中的this指向剛創(chuàng)建的內存空間
對象的__ proto__屬性能夠訪問到原型,IE下則沒有暴露出相應的屬性
3.使用指定的參數(shù)執(zhí)行構造函數(shù)中的代碼
因此相當于新建了一個Person對象寿酌,所以執(zhí)行b就是我們想要的結果
第二種情況(有返回值)
//返回數(shù)值類型
function Person1(name) {
this.name = name;
return this.name;
}
var a1= new Person1('張三'); //新建了一個Object 對象胰苏,它有一個name 屬性,并且返回一個字符串test
var b1 = Person1('李四'); // 函數(shù)Test()屬于Function對象醇疼,返回"test"字符串硕并,所以test2單純是一個字符串
console.log(a1)//Object
console.log(b1)//李四
console.log(a1.name)//張三
console.log(b1.name)//undefined
//返回引用類型
function Person2(name) {
this.name = name;
return [1,2,3];
}
var a2= new Person2('張三'); //新建了一個Object 對象,它有一個name 屬性秧荆,并且返回一個字符串test
var b2 = Person2('李四'); // 函數(shù)Test()屬于Function對象倔毙,返回"test"字符串,所以test2單純是一個字符串
console.log(a2)//[1,2,3]
console.log(b2)//[1,2,3]
console.log(a2==b2)//false
還是分兩種情況:
- 如果沒有new乙濒,但是函數(shù)有返回值陕赃,那么就會把返回值賦值給a
-
如果有new:
1.函數(shù)返回值為常規(guī)意義上的數(shù)值類型(Number卵蛉、String、Boolean)時么库,new函數(shù)將會返回一個該函數(shù)的實例對象
2.函數(shù)返回一個引用類型(Object傻丝、Array、Function)時诉儒,則new函數(shù)與直接調用函數(shù)產(chǎn)生的結果相同葡缰,執(zhí)行構造函數(shù)之后把引用類型返回
下面是chrome瀏覽器控制臺輸出的效果
Chrome控制臺