淺談JavaScript構(gòu)造函數(shù)

提到“構(gòu)造函數(shù)”,大部分人會(huì)聯(lián)想到Java類的概念,JavaScript也有構(gòu)造函數(shù),其使用語(yǔ)法與Java或者其他基于類的語(yǔ)言中創(chuàng)建對(duì)象的語(yǔ)法相似。

JavaScript構(gòu)造函數(shù)是一類比較特殊的函數(shù),特點(diǎn)為:

  • new關(guān)鍵字調(diào)用函數(shù)
  • 函數(shù)首字母大寫(xiě)

面試中,我經(jīng)常針對(duì)構(gòu)造函數(shù)問(wèn)兩個(gè)問(wèn)題:

  1. 構(gòu)造函數(shù)首字母必須大寫(xiě)嗎?
  2. 不用new關(guān)鍵字,直接運(yùn)行構(gòu)造函數(shù),是否會(huì)出錯(cuò)?如果不會(huì)出錯(cuò),那么,用new和不用new調(diào)用構(gòu)造函數(shù),有什么區(qū)別?

問(wèn)題1基本100%都能答對(duì)(大小寫(xiě)都可以),問(wèn)題2有20%同學(xué)會(huì)答錯(cuò),尤其是第二問(wèn)。

那么,讓我們看看new操作符到底起到什么作用?

1. 使用new操作符調(diào)用函數(shù)

例子:

function Person(name){
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
}

var person1 = new Person('nicole');
person1.say(); // "I am nicole"

new調(diào)用構(gòu)造函數(shù),函數(shù)內(nèi)部會(huì)發(fā)生如下變化:

  • 創(chuàng)建一個(gè)this變量,該變量指向一個(gè)空對(duì)象。并且該對(duì)象繼承函數(shù)的原型;
  • 屬性和方法被加入到this引用的對(duì)象中;
  • 隱式返回this對(duì)象(如果沒(méi)有顯性返回其他對(duì)象)

用偽程序來(lái)展示上述變化:

function Person(name){
  // 創(chuàng)建this變量,指向空對(duì)象
  var this = {}; 
  // 屬性和方法被加入到this引用的對(duì)象中
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
  // 返回this對(duì)象
  return this;
}

可以看出,用new調(diào)用構(gòu)造函數(shù),最大特點(diǎn)為,this對(duì)象指向構(gòu)造函數(shù)生成的對(duì)象,所以,person1.say()會(huì)返回字符串: "I am nicole"。

小貼士

如果指定了返回對(duì)象,那么,this對(duì)象可能被丟失。

function Person(name){
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
  var that = {};
  that.name = "It is that!";
  return that;
}

var person1 = new Person('nicole');
person1.name; // "It is that!"

2. 直接調(diào)用函數(shù)

如果直接調(diào)用函數(shù),那么,this對(duì)象指向window,并且,不會(huì)默認(rèn)返回任何對(duì)象(除非顯性聲明返回值)。

還是拿Person函數(shù)為例,直接調(diào)用Person函數(shù):

var person1 = Person('nicole');
person1; // undefined
window.name; // nicole

可見(jiàn),直接調(diào)用構(gòu)造函數(shù)的結(jié)果,并不是我們想要的。

3.小結(jié)

為了防止因?yàn)橥浭褂?code>new關(guān)鍵字而調(diào)用構(gòu)造函數(shù),可以加一些判斷條件強(qiáng)行調(diào)用new關(guān)鍵字,代碼如下:

function Person(name){
  if (!(this instanceof Person)) {
    return new Person(name);
  }
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
}

var person1 = Person('nicole');
console.log(person1.say()); // I am nicole
var person2 = new Person('lisa');
console.log(person2.say()); // I am lisa
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容