摘要:命令執(zhí)行時(shí),構(gòu)造函數(shù)內(nèi)部的,就代表了新生成的實(shí)例對(duì)象,表示實(shí)例對(duì)象有一個(gè)屬性,值是。因此,應(yīng)該非常小心,避免不使用命令直接調(diào)用構(gòu)造函數(shù)。命令返回這個(gè)對(duì)象,而不是對(duì)象。
JavaScript 面向?qū)ο缶幊痰幕A(chǔ)知識(shí)篇 1 。
1. 概述面向?qū)ο缶幊蹋∣bject Oriented Programming,縮寫(xiě)為 OOP)是目前主流的編程范式。
那么,“對(duì)象”(object)到底是什么?
對(duì)象是單個(gè)實(shí)物的抽象。
對(duì)象是一個(gè)容器,封裝了屬性(property)和方法(method)。 屬性是對(duì)象的狀態(tài),方法是對(duì)象的行為(完成某種任務(wù))。
2. 構(gòu)造函數(shù)面向?qū)ο缶幊痰牡谝徊剑褪且蓪?duì)象。通常需要一個(gè)模板,表示某一類(lèi)實(shí)物的共同特征,然后對(duì)象根據(jù)這個(gè)模板生成。
JavaScript 語(yǔ)言使用構(gòu)造函數(shù)(constructor)作為對(duì)象的模板。 “構(gòu)造函數(shù)”,就是專門(mén)用來(lái)生成實(shí)例對(duì)象的函數(shù)。
它就是對(duì)象的模板,描述實(shí)例對(duì)象的基本結(jié)構(gòu)。一個(gè)構(gòu)造函數(shù),可以生成多個(gè)實(shí)例對(duì)象,這些實(shí)例對(duì)象都有相同的結(jié)構(gòu)。
var Vehicle = function () {
this.price = 1000;
};
上面代碼中,Vehicle 就是構(gòu)造函數(shù)。為了與普通函數(shù)區(qū)別,構(gòu)造函數(shù)名字的第一個(gè)字母通常大寫(xiě)。
構(gòu)造函數(shù)的特點(diǎn)有兩個(gè)。
函數(shù)體內(nèi)部使用了 this 關(guān)鍵字,代表了所要生成的對(duì)象實(shí)例。
生成對(duì)象的時(shí)候,必須使用 new 命令。
3. new 命令new 命令的作用,就是執(zhí)行構(gòu)造函數(shù),返回一個(gè)實(shí)例對(duì)象。
var Vehicle = function () {
this.price = 1000;
};
var v = new Vehicle();
v.price // 1000
上面代碼通過(guò) new 命令,讓構(gòu)造函數(shù) Vehicle 生成一個(gè)實(shí)例對(duì)象,保存在變量 v 中。new 命令執(zhí)行時(shí),構(gòu)造函數(shù)內(nèi)部的this,就代表了新生成的實(shí)例對(duì)象,this.price 表示實(shí)例對(duì)象有一個(gè) price 屬性,值是1000。
下面兩行代碼是等價(jià)的,但是為了表示這里是函數(shù)調(diào)用,推薦使用括號(hào)。
// 推薦的寫(xiě)法
var v = new Vehicle();
// 不推薦的寫(xiě)法
var v = new Vehicle;
如果忘了使用 new 命令,直接調(diào)用構(gòu)造函數(shù)會(huì)發(fā)生什么事?
var Vehicle = function (){
this.price = 1000;
};
var v = Vehicle();
v // undefined
price // 1000
上面代碼中,調(diào)用 Vehicle 構(gòu)造函數(shù)時(shí),忘了加上 new 命令。結(jié)果,變量 v 變成了 undefined,而 price 屬性變成了全局變量。因此,應(yīng)該非常小心,避免不使用 new 命令、直接調(diào)用構(gòu)造函數(shù)。
為了保證構(gòu)造函數(shù)必須與 new 命令一起使用,有2種解決辦法:
構(gòu)造函數(shù)內(nèi)部使用嚴(yán)格模式,即第一行加上 use strict。 這樣的話,一旦忘了使用 new 命令,直接調(diào)用構(gòu)造函數(shù)就會(huì)報(bào)錯(cuò)。
function Fubar(foo, bar){
"use strict";
this._foo = foo;
this._bar = bar;
}
Fubar()
// TypeError: Cannot set property "_foo" of undefined
上面代碼的 Fubar 為構(gòu)造函數(shù),use strict 命令保證了該函數(shù)在嚴(yán)格模式下運(yùn)行。由于嚴(yán)格模式中,函數(shù)內(nèi)部的 this 不能指向全局對(duì)象,默認(rèn)等于undefined,導(dǎo)致不加 new 調(diào)用會(huì)報(bào)錯(cuò)(JavaScript 不允許對(duì) undefined添加屬性)。
構(gòu)造函數(shù)內(nèi)部判斷是否使用 new 命令,如果發(fā)現(xiàn)沒(méi)有使用,則直接返回一個(gè)實(shí)例對(duì)象。
function Fubar(foo, bar) {
if (!(this instanceof Fubar)) {
return new Fubar(foo, bar);
}
this._foo = foo;
this._bar = bar;
}
Fubar(1, 2)._foo // 1
(new Fubar(1, 2))._foo // 1
使用 new 命令時(shí),它后面的函數(shù)依次執(zhí)行下面的步驟。
創(chuàng)建一個(gè)空對(duì)象,作為將要返回的對(duì)象實(shí)例。
將這個(gè)空對(duì)象的原型,指向構(gòu)造函數(shù)的 prototype 屬性。
將這個(gè)空對(duì)象賦值給函數(shù)內(nèi)部的 this 關(guān)鍵字。
開(kāi)始執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼。
也就是說(shuō),構(gòu)造函數(shù)內(nèi)部,this 指的是一個(gè)新生成的空對(duì)象,所有針對(duì) this 的操作,都會(huì)發(fā)生在這個(gè)空對(duì)象上。構(gòu)造函數(shù)之所以叫“構(gòu)造函數(shù)”,就是說(shuō)這個(gè)函數(shù)的目的,就是操作一個(gè)空對(duì)象(即this對(duì)象),將其“構(gòu)造”為需要的樣子。
如果構(gòu)造函數(shù)內(nèi)部有 return 語(yǔ)句,而且 return 后面跟著一個(gè)對(duì)象,new 命令會(huì)返回return 語(yǔ)句指定的對(duì)象;否則,就會(huì)不管return語(yǔ)句,返回 this 對(duì)象。
var Vehicle = function () {
this.price = 1000;
return 1000;
};
(new Vehicle()) === 1000
// false new命令忽略了這個(gè) return 語(yǔ)句,返回“構(gòu)造”后的 this 對(duì)象。
如果 return語(yǔ)句返回的是一個(gè)跟 this 無(wú)關(guān)的新對(duì)象,new命令會(huì)返回這個(gè)新對(duì)象,而不是this對(duì)象。
var Vehicle = function (){
this.price = 1000;
return { price: 2000 };
};
(new Vehicle()).price
// 2000 new 命令返回這個(gè)對(duì)象,而不是 this 對(duì)象。
如果對(duì)普通函數(shù)(內(nèi)部沒(méi)有 this 關(guān)鍵字的函數(shù))使用 new 命令,則會(huì)返回一個(gè)空對(duì)象。
function getMessage() {
return "this is a message";
}
var msg = new getMessage();
msg // {}
typeof msg // "object"
這是因?yàn)?new 命令總是返回一個(gè)對(duì)象,要么是實(shí)例對(duì)象,要么是return 語(yǔ)句指定的對(duì)象。本例中,return 語(yǔ)句返回的是字符串,所以new 命令就忽略了該語(yǔ)句。
參考鏈接阮一峰, JavaScript 教程
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/6932.html
摘要:應(yīng)該非常小心,避免出現(xiàn)不使用命令直接調(diào)用構(gòu)造函數(shù)的情況。上面代碼表示,使用屬性,確定實(shí)例對(duì)象的構(gòu)造函數(shù)是,而不是。當(dāng)然,從繼承鏈來(lái)看,只有一個(gè)父類(lèi),但是由于在的實(shí)例上,同時(shí)執(zhí)行和的構(gòu)造函數(shù),所以它同時(shí)繼承了這兩個(gè)類(lèi)的方法。 基本概念 類(lèi)和實(shí)例是大多數(shù)面向?qū)ο缶幊陶Z(yǔ)言的基本概念 類(lèi):類(lèi)是對(duì)象的類(lèi)型模板 實(shí)例:實(shí)例是根據(jù)類(lèi)創(chuàng)建的對(duì)象但是,JavaScript語(yǔ)言的對(duì)象體系,不是基于類(lèi)的,...
摘要:在面向?qū)ο蟮恼Z(yǔ)言中,比如,等,單例模式通常是定義類(lèi)時(shí)將構(gòu)造函數(shù)設(shè)為,保證對(duì)象不能在外部被出來(lái),同時(shí)給類(lèi)定義一個(gè)靜態(tài)的方法,用來(lái)獲取或者創(chuàng)建這個(gè)唯一的實(shí)例。 萬(wàn)事開(kāi)頭難,作為正經(jīng)歷菜鳥(niǎo)賽季的前端player,已經(jīng)忘記第一次告訴自己要寫(xiě)一些東西出來(lái)是多久以的事情了。。。如果,你也和我一樣,那就像我一樣,從現(xiàn)在開(kāi)始,從看到這篇文章開(kāi)始,打開(kāi)電腦,敲下你的第一篇文章(或者任何形式的文字)吧。 ...
摘要:注意事項(xiàng)聲明函數(shù)時(shí)候處理業(yè)務(wù)邏輯區(qū)分和單例的區(qū)別,配合單例實(shí)現(xiàn)初始化構(gòu)造函數(shù)大寫(xiě)字母開(kāi)頭推薦注意的成本。簡(jiǎn)單工廠模式使用一個(gè)類(lèi)通常為單體來(lái)生成實(shí)例。 @(書(shū)籍閱讀)[JavaScript, 設(shè)計(jì)模式] 常見(jiàn)設(shè)計(jì)模式 一直對(duì)設(shè)計(jì)模式不太懂,花了一下午加一晚上的時(shí)間,好好的看了看各種設(shè)計(jì)模式,并總結(jié)了一下。 設(shè)計(jì)模式簡(jiǎn)介 設(shè)計(jì)模式概念解讀 設(shè)計(jì)模式的發(fā)展與在JavaScript中的應(yīng)用 ...
摘要:因此,就會(huì)形成一個(gè)原型鏈對(duì)象到原型,再到原型的原型如果一層層地上溯,所有對(duì)象的原型最終都可以上溯到,即構(gòu)造函數(shù)的屬性。 對(duì)于很多前端開(kāi)發(fā)者而言,JavaScript中原型與原型鏈?zhǔn)且粋€(gè)比較容易疑惑的點(diǎn),所以本文記錄了自己對(duì)應(yīng)這方面的一點(diǎn)理解,以后有更深的理解再來(lái)更新。 對(duì)象 想要了解原型與原型鏈,首先要了解什么是對(duì)象?面向?qū)ο缶幊蹋∣bject Oriented Programmin...
摘要:結(jié)果會(huì)被存放到拷貝文件目錄你可以使用方法拷貝文件目錄到新路徑,所有操作都相對(duì)于項(xiàng)目根目錄版本號(hào)緩存刷新很多開(kāi)發(fā)者會(huì)給編譯的前端資源添加時(shí)間戳或者唯一令牌后綴以強(qiáng)制瀏覽器加載最新版本而不是代碼的緩存副本。 環(huán)境準(zhǔn)備 1、安裝 nodejs 和 npm ?如果你使用的是 Laravel 的 Homestead 環(huán)境,可以不用安裝了,已自帶。 ?我們來(lái)查看下它們的版本: $ node -v ...
閱讀 2702·2023-04-26 00:07
閱讀 2458·2021-11-15 11:37
閱讀 678·2021-10-19 11:44
閱讀 2203·2021-09-22 15:56
閱讀 1766·2021-09-10 10:50
閱讀 1530·2021-08-18 10:21
閱讀 2597·2019-08-30 15:53
閱讀 1656·2019-08-30 11:11