日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

深入浅出面向对象和原型【番外篇——重新认识new】

發(fā)布時(shí)間:2025/3/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入浅出面向对象和原型【番外篇——重新认识new】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

我們?cè)谏钊霚\出面向?qū)ο蠛驮汀靖拍钇?】在這篇文章中了解到了如何使用new Function解決重復(fù)創(chuàng)建浪費(fèi)內(nèi)存的問(wèn)題,其中的關(guān)鍵就是new,那么這篇文章讓我們來(lái)重新了解new的前世今生

一個(gè)苦逼年級(jí)主任的故事

開(kāi)學(xué)啦~~~高一年級(jí)主任龔主任需要為全年級(jí)每一位理科班新生錄入學(xué)號(hào)并為每一位學(xué)生生成相關(guān)檔案
不僅要自己留一份而且要把每一個(gè)檔案都上傳到學(xué)校資料庫(kù)
哇,全年級(jí)一千個(gè)學(xué)生,一個(gè)個(gè)輸入,不要命啦?
還好龔主任學(xué)過(guò)編程

// 先造一個(gè)對(duì)象,把相關(guān)數(shù)據(jù)都先寫(xiě)進(jìn)去,看看是啥樣的var 學(xué)生 = {學(xué)號(hào): 1,年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}}// 不錯(cuò),檔案大致就是如此// 再來(lái)個(gè)數(shù)組自己留著作為備份// 那么循環(huán)一千次吧var 全年級(jí)學(xué)生 = []for (var i = 0; i < 1000; i++) {var 學(xué)生 = {學(xué)號(hào): i,年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}}全年級(jí)學(xué)生.push(學(xué)生)}

龔主任突然想到,他昨天晚上在才在segmentfault上看到有關(guān)于內(nèi)存浪費(fèi)的文章——深入淺出面向?qū)ο蠛驮汀靖拍钇?】
那么他寫(xiě)的這個(gè)代碼就是典型的內(nèi)存浪費(fèi)啊
每個(gè)學(xué)生除了學(xué)號(hào)不同,其它都相同,咋辦呢?
哎對(duì)了,那篇文章說(shuō)可以通過(guò)原型和原型鏈解決這個(gè)問(wèn)題
那么試試吧

// 先創(chuàng)建一個(gè)學(xué)生原型,然后把相同的代碼都放在這里var 學(xué)生原型 = {年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}}// 重新寫(xiě)循環(huán)代碼var 全年級(jí)學(xué)生 = []for (var i = 0; i < 1000; i++) {var 學(xué)生 = {學(xué)號(hào): i}// 還記得嗎,每個(gè)對(duì)象自動(dòng)帶有__proto__屬性// 不過(guò)在這里__proto__屬性的指向需要我們自己去設(shè)定學(xué)生.__proto__ = 學(xué)生原型全年級(jí)學(xué)生.push(學(xué)生)}

好了,大功告成,這下內(nèi)存不浪費(fèi)了
但是,龔主任聽(tīng)說(shuō)程序猿寫(xiě)代碼都追求可讀性強(qiáng),他這寫(xiě)的太不優(yōu)雅了
再改改吧

// 優(yōu)雅的代碼離不開(kāi)封裝,現(xiàn)在讓我們來(lái)封裝封裝吧function 學(xué)生(學(xué)號(hào)) {// 我們先建立一個(gè)臨時(shí)對(duì)象,把例如學(xué)號(hào)之類(lèi)需要改變的屬性放進(jìn)去var 臨時(shí)對(duì)象 = {}臨時(shí)對(duì)象.學(xué)號(hào) = 學(xué)號(hào)// 再把臨時(shí)對(duì)象的__proto__手工綁定到學(xué)生.原型臨時(shí)對(duì)象.__proto__ = 學(xué)生.原型return 臨時(shí)對(duì)象}學(xué)生.原型 = {年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}}// 好了,開(kāi)始循環(huán)吧var 學(xué)生們 = []for (var i = 0; i < 1000; i++) {學(xué)生們.push(學(xué)生(i))} 好了,讓我們先遠(yuǎn)離一下龔先生和他的代碼,來(lái)看看到底什么是new function 學(xué)生(學(xué)號(hào)) {// 我們先建立一個(gè)臨時(shí)對(duì)象,把例如學(xué)號(hào)之類(lèi)需要改變的屬性放進(jìn)去// 【new做的第一件事:幫你創(chuàng)立一個(gè)臨時(shí)對(duì)象,臨時(shí)對(duì)象通過(guò)this訪問(wèn)】var 臨時(shí)對(duì)象 = {}臨時(shí)對(duì)象.學(xué)號(hào) = 學(xué)號(hào)// 再把臨時(shí)對(duì)象的__proto__手工綁定到學(xué)生原型// 【new做的第二件事:幫你自動(dòng)把__proto__綁定到學(xué)生.原型】臨時(shí)對(duì)象.__proto__ = 學(xué)生.原型// 【new做的第三件事:幫你return臨時(shí)對(duì)象】return 臨時(shí)對(duì)象}// 【但new只有一個(gè)要求:把學(xué)生原型改名為 學(xué)生.prototype】學(xué)生.原型 = {年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}} 那么,我們用new該怎么寫(xiě)?so easy。new幫你做的事,你還自己做它干嘛呢? function 學(xué)生(學(xué)號(hào)) {// 【new做的第一件事:幫你創(chuàng)立一個(gè)臨時(shí)對(duì)象,臨時(shí)對(duì)象通過(guò)this訪問(wèn)】// 所以我們不用創(chuàng)建臨時(shí)對(duì)象了,把下面那行代碼注釋掉// var 臨時(shí)對(duì)象 = {}// 把臨時(shí)對(duì)象都改為this就好this.學(xué)號(hào) = 學(xué)號(hào)// 再把臨時(shí)對(duì)象的__proto__手工綁定到學(xué)生原型// 【new做的第二件事:幫你自動(dòng)把__proto__綁定到學(xué)生原型】// 我們不用手動(dòng)綁定了,注釋掉// 臨時(shí)對(duì)象.__proto__ = 學(xué)生原型// 【new做的第三件事:幫你return臨時(shí)對(duì)象】// 我們不用手動(dòng)return了,注釋掉// return 臨時(shí)對(duì)象}// 【但new只有一個(gè)要求:把學(xué)生原型改名為 學(xué)生.prototype】// new 幫了我們這么多忙,按照他的意思來(lái)唄,改了!學(xué)生.prototype = {年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}}var 學(xué)生們 = []for (var i = 0; i < 1000; i++) {學(xué)生們.push(new 學(xué)生(i)) 我的天哪,我們的代碼竟然通過(guò)new減少了這么多!!

constructor屬性

function test(id) {this.id = id}new test(1)console.log(test.prototype) // {constructor: ?}

使用new操作符的時(shí)候,為了記錄臨時(shí)對(duì)象是由哪個(gè)函數(shù)創(chuàng)建的,會(huì)在prototype里添加一個(gè)constructor屬性,指向創(chuàng)建臨時(shí)對(duì)象的函數(shù)
注意:如果直接給prototype賦值,則constructor屬性會(huì)消失

function 學(xué)生(學(xué)號(hào)) {this.學(xué)號(hào) = 學(xué)號(hào)}學(xué)生.prototype = {年級(jí): '高一',所選方向: '理科班',上傳資料: function () {/*上傳資料的代碼*/}}var 學(xué)生們 = []for (var i = 0; i < 1000; i++) {學(xué)生們.push(new 學(xué)生(i))}// 沒(méi)有出現(xiàn)constructor屬性console.log(學(xué)生.prototype) // {年級(jí): "高一", 所選方向: "理科班", 上傳資料: ?}

可以采用另一種賦值方式

function 學(xué)生(學(xué)號(hào)) {this.學(xué)號(hào) = 學(xué)號(hào)}學(xué)生.prototype.年級(jí) = '高一'學(xué)生.prototype.所選方向 = '理科班'學(xué)生.prototype.上傳資料 = function () {/*上傳資料的代碼*/}var 學(xué)生們 = []for (var i = 0; i < 1000; i++) {學(xué)生們.push(new 學(xué)生(i))}// 出現(xiàn)constructor屬性console.log(學(xué)生.prototype) // {年級(jí): "高一", 所選方向: "理科班", 上傳資料: ?, constructor: ?}

總結(jié)

new的本質(zhì)

new的本質(zhì)其實(shí)就是一個(gè)語(yǔ)法糖,目的就是為了幫我們省代碼

new的作用

  • 創(chuàng)立一個(gè)臨時(shí)對(duì)象,臨時(shí)對(duì)象指向類(lèi)的this
  • 把實(shí)例__proto__綁定到類(lèi)的prototype
  • return臨時(shí)對(duì)象(也就是this)
  • 關(guān)于new的語(yǔ)法糖

    var a = {} 是 var a = new Object()的語(yǔ)法糖 var a = [] 是 var a = new Array()的語(yǔ)法糖 var a = funciton(){} 是 var a = new Function()的語(yǔ)法糖

    參考

    new運(yùn)算符
    JS 的 new 到底是干什么的?

    總結(jié)

    以上是生活随笔為你收集整理的深入浅出面向对象和原型【番外篇——重新认识new】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。