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

