new操作符干了什么?
我們可以一起通過代碼實(shí)現(xiàn)來看看new關(guān)鍵字到底做了一些什么事情
function Book(name) {
this.name = name;
}
Book.prototype.say = function() {
console.log(this.name);
};
let book = new Book('javascript高級(jí)程序設(shè)計(jì)');
console.log(book);
book.say();
輸出結(jié)果如下圖:

上例中,new關(guān)鍵字調(diào)用的構(gòu)造函數(shù)并沒有任何返回值,最終我們實(shí)例創(chuàng)建了一個(gè)對(duì)象,那如果構(gòu)造函數(shù)擁有返回值呢?new關(guān)鍵字會(huì)如何處理
function Test(name) {
this.conname = name;
return 1
}
Test.prototype.say = function() {
console.log(this.conname);
};
let test = new Test('測(cè)試');
console.log(test);
test.say();

上例中,構(gòu)造函數(shù)返回了一個(gè)基本數(shù)據(jù)類型的值,而最終我們依舊拿到了想要的實(shí)例對(duì)象。那如果構(gòu)造函數(shù)返回一個(gè)引用類型的值呢?
function Test(name) {
this.conname = name;
return {
name
}
}
Test.prototype.say = function() {
console.log(this.conname);
};
let test = new Test('測(cè)試');
console.log(test);
test.say();
上例中,構(gòu)造函數(shù)最終返回了一個(gè)對(duì)象,這個(gè)對(duì)象上有name屬性,然后在構(gòu)造函數(shù)的prototype上,還擁有say方法,我們看看這次new得到的值是什么,是否擁有構(gòu)造函數(shù)prototype上的方法

可以看到的是,我們拿到的對(duì)象是最終構(gòu)造函數(shù)return出來的那個(gè)對(duì)象,而這個(gè)對(duì)象頁沒有構(gòu)造函數(shù)prototype上的say方法
經(jīng)過測(cè)試,我們發(fā)現(xiàn)
- new關(guān)鍵字 通過構(gòu)造函數(shù)創(chuàng)建出來的實(shí)例可以訪問到構(gòu)造函數(shù)中的屬性
- new關(guān)鍵字 通過構(gòu)造函數(shù)創(chuàng)建出來的實(shí)例可以訪問到構(gòu)造函數(shù)原型鏈中的屬性,也就是說通過 new 操作符,實(shí)例與構(gòu)造函數(shù)通過原型鏈連接了起來
- new關(guān)鍵字 操作的構(gòu)造函數(shù)如果返回基本類型,那么這個(gè)返回值毫無意義
- new關(guān)鍵字 操作的構(gòu)造函數(shù)如果返回引用類型,那么這個(gè)返回值會(huì)被正常使用
通過上述的一些測(cè)試,我們可以自己試著實(shí)現(xiàn)一下new關(guān)鍵字;
自己實(shí)現(xiàn)new關(guān)鍵字
function Book(name) {
this.name = name;
}
Book.prototype.say = function() {
console.log(this.name);
};
function myNew(Constructor, ...args) {
let obj = {};
obj.__proto__ = Constructor.prototype;
let result = Constructor.call(obj, ...args);
return result instanceof Object ? result : obj;
}
let book = myNew(Book, 'javascript高級(jí)程序設(shè)計(jì)');
console.log(book);
book.say();
// 本文由郝晨光整理并總結(jié),未經(jīng)授權(quán)禁止轉(zhuǎn)載

總結(jié) new關(guān)鍵字到底做了些什么
- 先創(chuàng)建了一個(gè)新的空對(duì)象
- 然后讓這個(gè)空對(duì)象的proto指向函數(shù)的原型prototype
- 將對(duì)象作為函數(shù)的this傳進(jìn)去,如果return 出來東西是對(duì)象的話就直接返回 return 的內(nèi)容,沒有的話就返回創(chuàng)建的這個(gè)對(duì)象
null和undefined的區(qū)別?
在javascript中,null和undefined都用來表示一個(gè)空的值,
null
null類型,代表“空值”,代表一個(gè)空對(duì)象指針,使用typeof運(yùn)算得到 “object”,所以你可以認(rèn)為它是一個(gè)特殊的對(duì)象值。
使用場(chǎng)景:
- 作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)不是對(duì)象;
- 作為對(duì)象原型鏈的終點(diǎn)。
undefined
undefined類型,代表“未定義”,代表一個(gè)變量已經(jīng)聲明但是還未賦值,就是此處應(yīng)該有一個(gè)值,但是還沒有定義。
使用場(chǎng)景:
- 變量被聲明了,但沒有賦值時(shí),就等于undefined。
- 調(diào)用函數(shù)時(shí),應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于undefined。
- 對(duì)象沒有賦值的屬性,該屬性的值為undefined。
- 函數(shù)沒有返回值時(shí),默認(rèn)返回undefined。
eval是做什么的?
eval用來將字符串解析為javascript代碼并執(zhí)行
// 聲明變量
const str = "var a = 5,b = 10;"
eval(str);
console.log(a); // 5
console.log(b); // 10
// 返回運(yùn)算值
const str2 = "5+10";
console.log(eval(str2)); // 15
// 本文由郝晨光整理并總結(jié),未經(jīng)授權(quán)禁止轉(zhuǎn)載
eval還可以將JSON字符串轉(zhuǎn)換為JSON對(duì)象,例如:
const JSONStr = '[{name: "張三",age: 25},{name: "李四", age: 30}]';
let JSONObj = eval(JSONStr);
console.log(JSONObj); // [{name: "張三",age: 25},{name: "李四", age: 30}]
需要注意的是:我們應(yīng)該避免使用eval,它并不安全,而且非常耗性能(需要先將字符串轉(zhuǎn)換為javascript代碼,然后再執(zhí)行)。
iframe的優(yōu)缺點(diǎn)
什么是iframe?
iframe就是框架網(wǎng)頁就是在同一個(gè)頁面里有多個(gè)網(wǎng)頁,使用框架的好處就是你在請(qǐng)求一個(gè)網(wǎng)頁的下一個(gè)頁面的時(shí)候,還有 一個(gè)網(wǎng)頁是一直顯示著的,這樣瀏覽者就不會(huì)就的等待的存在了;
iframe也稱作嵌入式框架,嵌入式框架和框架網(wǎng)頁類似,它可以把一個(gè)網(wǎng)頁的框架和內(nèi)容嵌入在現(xiàn)有的網(wǎng)頁中。
iframe的使用方法
iframe使用很簡(jiǎn)單,使用src屬性指向另一個(gè)你需要包含的另一個(gè)文件即可,也可以設(shè)置元素的寬,高等。比如:
<iframe
name="list-frame" // 規(guī)定 iframe 的名稱。
marginwidth="0" // 定義 iframe 的左側(cè)和右側(cè)的邊距。
marginheight="0" // 定義 iframe 的頂部和底部的邊距。
width="100%" // 定義 iframe 的寬度。
height="300px" // 規(guī)定 iframe 的高度。
src="list.html" // 規(guī)定在 iframe 中顯示的文檔的 URL。
frameborder="0" // 規(guī)定是否顯示框架周圍的邊框。取值:0/1
scrolling="auto" // 規(guī)定是否在 iframe 中顯示滾動(dòng)條。取值:yes/no/auto
></iframe>
iframe的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- iframe能夠原封不動(dòng)的把嵌入的網(wǎng)頁展現(xiàn)出來。
- 如果有多個(gè)網(wǎng)頁引用iframe,那么你只需要修改iframe的內(nèi)容,就可以實(shí)現(xiàn)調(diào)用的每一個(gè)頁面內(nèi)容的更改,方便快捷。
- 網(wǎng)頁如果為了統(tǒng)一風(fēng)格,頭部和版本都是一樣的,就可以寫成一個(gè)頁面,用iframe來嵌套,可以增加代碼的可重用。
- 如果遇到加載緩慢的第三方內(nèi)容如圖標(biāo)和廣告,這些問題可以由iframe來解決。
缺點(diǎn)
- 頁面樣式調(diào)試麻煩,出現(xiàn)多個(gè)滾動(dòng)條;
- 瀏覽器的后退按鈕失效;
- 過多會(huì)增加服務(wù)器的HTTP請(qǐng)求;
- 小型的移動(dòng)設(shè)備無法完全顯示框架;
- 產(chǎn)生多個(gè)頁面,不易管理;
- 不容易打?。?/li>
- iframe會(huì)阻塞主頁面的Onload事件
- 占用資源。每增加一個(gè) iframe,相當(dāng)于多增加一個(gè)獨(dú)立的窗口,每個(gè) iframe 中都需要占用獨(dú)立的資源。
- 代碼復(fù)雜,無法被一些搜索引擎解讀。
如果本文對(duì)您有幫助,可以看看本人的其他文章:
前端常見面試題(九)@郝晨光
前端常見面試題(八)@郝晨光
前端常見面試題(七)@郝晨光
友情鏈接:純?cè)鷮?shí)現(xiàn)彈出層 @程程程