JavaScript中的new操作符的具體使用
JavaScript中的new操作符是一個(gè)非常重要的概念,它可以讓我們創(chuàng)建一個(gè)自定義的對(duì)象類型或者一個(gè)內(nèi)置的對(duì)象類型,比如Array、Date、Function等。那么,new操作符到底做了什么呢?我們來一步一步分析。
new做了什么?
首先,當(dāng)我們使用new操作符調(diào)用一個(gè)函數(shù)時(shí),這個(gè)函數(shù)就會(huì)被當(dāng)作一個(gè)構(gòu)造函數(shù),也就是說,它會(huì)用來創(chuàng)建一個(gè)新的對(duì)象實(shí)例。例如:
function Person(name) { this.name = name; } var p1 = new Person("Allen");
這里,我們定義了一個(gè)Person
函數(shù),然后用new操作符創(chuàng)建了一個(gè)p1
對(duì)象,這個(gè)對(duì)象的類型是Person
,它有個(gè)name
屬性,賦值為"Allen"
。
那么,具體來說,new操作符做了哪些事情呢?我們可以總結(jié)為以下四個(gè)步驟:
- 創(chuàng)建一個(gè)空的JavaScript對(duì)象,我們暫且叫它
newInstance
。 - 將newInstance的
[[Prototype]]
屬性指向構(gòu)造函數(shù)的prototype
屬性,如果prototype
是一個(gè)對(duì)象的話。否則,newInstance保持為一個(gè)普通對(duì)象,它的[[Prototype]]
指向Object.prototype
。注意:[[Prototype]]
是一個(gè)內(nèi)部屬性,它表示對(duì)象的原型鏈。通過這一步,newInstance就可以繼承構(gòu)造函數(shù)原型上的屬性和方法。 - 執(zhí)行構(gòu)造函數(shù),并將newInstance作為this的上下文(也就是說,在構(gòu)造函數(shù)中所有對(duì)this的引用都指向newInstance)。這樣,構(gòu)造函數(shù)就可以給newInstance添加一些自身的屬性和方法。
- 如果構(gòu)造函數(shù)返回了一個(gè)非原始值(比如一個(gè)對(duì)象或者一個(gè)函數(shù)),那么這個(gè)返回值就會(huì)成為整個(gè)new表達(dá)式的結(jié)果。否則,如果構(gòu)造函數(shù)沒有返回任何值或者返回了一個(gè)原始值(比如一個(gè)數(shù)字或者一個(gè)字符串),那么newInstance就會(huì)成為整個(gè)new表達(dá)式的結(jié)果。(通常情況下,構(gòu)造函數(shù)不會(huì)返回任何值,但是它可以選擇這樣做來覆蓋正常的對(duì)象創(chuàng)建過程。)
例如:
function Foo(bar) { this.bar = bar; } Foo.prototype.baz = function() { console.log(this.bar); }; var f1 = new Foo("Hello"); // f1是Foo類型的對(duì)象,它有bar屬性和baz方法 var f2 = new Foo("World"); // f2也是Foo類型的對(duì)象,它也有bar屬性和baz方法 f1.baz(); // Hello f2.baz(); // World function Bar() { return { name: "Bar" }; } var b1 = new Bar(); // b1是一個(gè)普通對(duì)象,它有name屬性 console.log(b1 instanceof Bar); // false
這里,我們定義了兩個(gè)函數(shù)Foo和Bar,并用new操作符創(chuàng)建了f1、f2和b1三個(gè)對(duì)象。可以看到,f1和f2都是Foo類型的對(duì)象,它們繼承了Foo.prototype上的baz方法,并且有自己的bar屬性。而b1則是一個(gè)普通對(duì)象,它只有name屬性,并不屬于Bar類型,因?yàn)锽ar函數(shù)返回了一個(gè)對(duì)象。
如何手寫一個(gè)new
底層實(shí)現(xiàn)上,class還是基于原型繼承和構(gòu)造函數(shù)的?;谶@個(gè)理解:
function newInstance(constructor, ...args) { // 創(chuàng)建一個(gè)空對(duì)象,且 __proto__ 指向 constructor.prototype const obj = Object.create(constructor.prototype); // 執(zhí)行構(gòu)造函數(shù)并綁定 this 到新對(duì)象上 const result = constructor.apply(obj, args); // 如果構(gòu)造函數(shù)返回了一個(gè)對(duì)象,則返回該對(duì)象 if (result && (typeof result === "object" || typeof result === "function")) { return result; } // 否則返回新對(duì)象 return obj; } // 示例使用 function Person(name) { this.name = name; } Person.prototype.greet = function() { console.log(`Hello, I'm ${this.name}.`); }; const person1 = newInstance(Person, "Allen"); person1.greet(); // 輸出 "Hello, I'm Allen."
上述代碼中,myNew
函數(shù)模擬了 new
操作符的行為,它接受兩個(gè)參數(shù):構(gòu)造函數(shù)和構(gòu)造函數(shù)的參數(shù),返回一個(gè)新的實(shí)例對(duì)象。在函數(shù)內(nèi)部,首先創(chuàng)建了一個(gè)新的空對(duì)象 obj
,然后將該對(duì)象的 __proto__
屬性指向構(gòu)造函數(shù)的原型對(duì)象,從而實(shí)現(xiàn)了原型繼承。接著將構(gòu)造函數(shù)的 this
綁定到新對(duì)象上,并執(zhí)行構(gòu)造函數(shù)。如果構(gòu)造函數(shù)返回的是一個(gè)對(duì)象,則直接返回該對(duì)象,否則返回新創(chuàng)建的對(duì)象 obj
。
到此這篇關(guān)于JavaScript中的new操作符的具體使用的文章就介紹到這了,更多相關(guān)JavaScript new操作符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
整理一些JavaScript的IE和火狐的兼容性注意事項(xiàng)
整理一些JavaScript的IE和火狐的兼容性解決方法,有更好的方法多多交流2011-03-03關(guān)于Javascript中defer和async的區(qū)別總結(jié)
相信看過javascript高級(jí)程序設(shè)計(jì)的人,在javascript高級(jí)程序設(shè)計(jì)里,應(yīng)該看到了介紹了有關(guān)defer和async的區(qū)別,可是比較淺顯,而且也說得不是很清楚。下面我們來通過這篇文章來詳細(xì)了解下dfer和async的區(qū)別。2016-09-09javascript中如何處理引號(hào)編碼"
本文為大家介紹下javascript中如何處理引號(hào)編碼,具體如下,感興趣的朋友可以參考下2013-08-08javascript關(guān)于運(yùn)動(dòng)的各種問題經(jīng)典總結(jié)
這篇文章主要介紹了javascript關(guān)于運(yùn)動(dòng)的各種問題,實(shí)例總結(jié)了javascript關(guān)于滾動(dòng)的常見錯(cuò)誤、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04js createRange與createTextRange的一些用法實(shí)例
關(guān)于createTextRange和createRange的一些用法,腳本之家增強(qiáng)版。2010-05-05JavaScript面試Module?Federation實(shí)現(xiàn)原理詳解
這篇文章主要為大家介紹了JavaScript面試Module?Federation實(shí)現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10JavaScript實(shí)現(xiàn)九九乘法表的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)硪黄狫avaScript實(shí)現(xiàn)九九乘法表的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06HTML+CSS+JavaScript實(shí)現(xiàn)放大鏡效果
這篇文章主要為大家詳細(xì)介紹了HTML+CSS+JavaScript實(shí)現(xiàn)放大鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07Bootstrap FileInput實(shí)現(xiàn)圖片上傳功能
這篇文章主要為大家詳細(xì)介紹了Bootstrap FileInput實(shí)現(xiàn)圖片上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01