- 重排重繪
__proto__
和prototype
分別是什麼- 哪種情況下
__proto__
和prototype
的指向是同一個? - 原型鏈原理
- 在原型鏈上
Object
再往上是什麼 new
和Object.create
的區別typeof array null undefined NaN
分別是什麼- 把
undefined
和null
轉成Number
分別是什麼 - 如何判斷是否爲數組?
instanceof
和constructor
的區別
1. 重排、重繪
- 重排
重排是根據渲染樹中每個渲染對象的信息,計算出各個渲染對象的幾何信息(即DOM對象的位置和尺寸大小),將各個渲染對象放置在頁面的正確位置。
某個DOM節點的幾何信息更改,就需要重新計算,然後重新佈局。即導致重排。
引發重排的操作:
- 頁面的首次渲染
- 瀏覽器的窗口大小發生改變
DOM
元素位置和尺寸發生改變- 元素的內容發生改變(比如:文字數量或圖片大小等)
- 文本元素字體大小發生改變
- 添加或刪除可見的
DOM
元素 - 激活
CSS
的僞類(比如::hover
) - 設置
style
屬性(width,height,margin,padding,border
等等) - 查詢某些屬性或調用某些方法(
scrollIntoView(),scrollTo(),scrollIntoView()
等等)
- 重繪
重繪是當頁面元素的樣式改變且不影響該元素在文檔流中的位置就會發生重繪。比如,改變元素的顏色等
常見引起重回的樣式屬性有:
color
border-style
visibility
background
text-decoration
background-image
background-position
background-repeat
outline-color
outline
outline-style
border-radius
outline-width
box-shadow
background-size
補充:DOM操作是一項高成本的操作,儘量減少重排。
2. __proto__
和prototype
分別是什麼
其實可以理解爲prototype
是構造函數的屬性,__proto__
是實例對象的屬性,他們都指向同一個對象
function Person(){
}
let person1 = new Person();
person1.__proto__ === Person.prototype; // true
記住2點就夠了
- 每個對象都有一個
__proto__
屬性指向它構造函數的prototype
- 每個構造函數都有一個
prototype
原型對象,同樣這個原型對象也有一個__proto__
屬性。
3. 哪種情況下__proto__
和prototype
的指向是同一個?
Function.__proto__ === Function.prototype; // true
4. 原型鏈原理(點擊查看原型鏈和繼承相關知識)>>
5. 在原型鏈上Object
再往上是什麼
null
Object
的實例,處於原型鏈的末端,因而它沒有原型。
6. new
和Object.create
的區別
new
一個對象發生了什麼?
- 創建了並返回一個新的對象
- 對象內
this
指向這個新的對象
function F(){
this.a = 1;
}
const obj = new F()
obj.a; // 1
使用new操作符創建的對象具備原來對象的屬性
Object.create
:
- 創建一個新對象
- 語法
Object.create ( proto, [ propertiesObject ] )
參數:
- 第一個參數
proto
是一個對象或者構造函數,作爲新對象的原型 - 第二個參數
propertiesObject
(可選),爲這個新對象添加屬性
function F(){
this.a = 1;
}
const obj = Object.create(F,{
b: {
value: 2
}
});
obj.a; // undefined
obj.b; // 2
可見:Object.create()創建的新對象丟失了原來對象的屬性
7. typeof array null undefined NaN
分別是什麼
typeof [數組]; // object
typeof null; // object
typeof undefined; // undefined
typeof NaN; //number
8. 把undefined
和null
轉成Number
分別是什麼
Number(null); // 0
Number(undefined); // NaN
9. 如何判斷是否爲數組?
- 使用
instanceof
const arr = [1,2,3];
arr instanceof Array; // true
- 使用
constructor
const arr = [1,2,3];
arr.constructor === Array; // true
- 使用
Object.prototype.toString()
方法
const arr = [1,2,3];
Object.prototype.toString.call(arr) === "[object Array]"; // true
- 使用ES6提供的Array.isArray()方法
const arr = [1,2,3];
Array.isArray(arr); // true
10. instanceof
和constructor
的區別
constructor
- 我們創建的每一個函數都有一個
prototype
原型屬性,這個屬性是一個指針,指向一個對象。默認的情況下,所有的原型對象有一個構造函數constructor
屬性,這個屬性是一個指向prototype
屬性所在函數的指針。 constructor
屬性在構造函數的原型裏,並且指向構造函數,就可以利用constructor
屬性來判斷一個實例對象是由哪個構造函數構造出來的,也可以說判斷它屬於哪個類。- ⚠️當構造函數
Person.prototype
等於一個字面量定義出來的對象時,constructor
屬性不再指向這個構造函數Person
(即原型鏈重寫會導致constructor
指向改變或constuctor
不復存在)
instanceof
instanceof
運算符是用來判斷某個實例對象是否由某個構造函數構造而來(這點和constructor
的作用相同)- ⚠️ 但是原型鏈重寫並不會影響
instanceof
的判斷,因爲instanceof
是根據原型鏈來判斷構造函數的,只要對象實例的原型鏈不發生變化,instanceof
便可以正確判斷 instanceof
不僅可以判斷實例對象直接的構造函數,而且還能判斷原型鏈上所有的構造函數