我出的這套基礎題,面試(當面答題,想百度是不存在的)好多人,狀況都比較差,沒有令我滿意的,是我出題太難了麼? javascript
當咱們想要從 object 中讀取一個缺失的屬性時,js 會自動從原型中獲取它
舉例:
const animal = {
eats: true,
sleep: true,
voice: '',
bark(){
console.log(this.voice);
},
}
const dog = {
run: true,
voice: 'wang~~ wang~~',
}
dog.__proto__ = animal;
console.log(dog.run) // true
console.log(dog.eats) // true
console.log(dog.bark()) // wang~~ wang~~
console.log(dog.sleep) // true
總結:
全部的對象都有一個隱藏的 [[Prototype]] 屬性,它能夠是另外一個對象或者 null。
可使用 obj.__proto__ 進行訪問。
[[Prototype]] 引用的對象稱爲「原型」。
要讀取 obj 屬性或者調用一個方法,並且它不存在,那麼就會嘗試在原型中查找它。
寫/刪除直接在對象上進行操做,它們不使用原型(除非屬性其實是一個 setter)。
咱們調用 obj.method(),並且 method 是從原型中獲取的,this 仍然會引用 obj。
方法重視與當前對象一塊兒工做,即便它們是繼承的。
擴展:
構造函數繼承、組合繼承、寄生繼承、寄生組合式繼承。
複製代碼
防抖:
連續觸發的事件(高頻),在單位時間T內只執行最後一次,
若在T內再次觸發,則清空定時從新計算。場景:模糊搜索
節流:
連續觸發的事件(高頻),在單位時間T內只執行一次。窗口滾動,獲取滾動條top
複製代碼
若子域同源,則能夠經過設置document.domain將窗口視爲同源站點,進行通訊,
例如本地儲存等等方式。
若不一樣源,咱們能夠在經過 postMessage(data,targetOrigin) 這個接口,進行跨窗口通訊。
複製代碼
css
點擊劫持: 容許惡意網頁以用戶的名義點擊 「受害站點」。 一般惡意網頁在受害網站連接之上放置一個透明 <iframe> 標籤。 防範: 服務端 header 字段 X-Frame-Options 可以容許或禁止 frame 內頁面的顯示。 複製代碼複製代碼
鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,
可是並不會按線性的順序儲存數據,而是在每個節點裏存到下一個節點的指針(Pointer)。
因爲沒必要須按順序儲存,鏈表在插入的時候能夠達到 o(1)的複雜度,比另外一種線性表順序錶快得多,
可是查找一個節點或者訪問特定編號的節點則須要 o(n)的時間,而順序表響應的時間複雜度分別是 o(logn)和 o(1)。
特色:
無需預先分配內存,能夠充分利用計算機內存空間,實現靈活的內存動態管理
插入/刪除節點不影響其餘節點
隨機訪問速度較慢
增長告終點的指針域,空間開銷比較大
單向鏈表:
是鏈表中最簡單的一種,它包含兩個域,一個信息域和一個指針域。
這個連接指向列表中的下一個節點,而最後一個節點則指向一個空值。
應用:
git commit、es6的Iterator、react的fiber算法。
複製代碼
前端路由(spa)純瀏覽器行爲,是由瀏覽器控制的(hash、history),
當打開一個spa頁面後,切換路由,瀏覽器改變地址欄url並經過js展現對應頁面(組件)
後端路由,切換路由時,服務端會去匹配並查找對應資源,返回給瀏覽器並渲染。
複製代碼
本題相對開放一些。
webpack我的理解:
webpack是劃時代的,比較完美解決了前端模塊依賴的問題,任何資源都是js,任何資源均可以在js中聲明依賴,
真正實現了通用的模塊化開發。
loader的設計原則:
單一職責、全部模塊都是js模塊,webpack 只支持js模塊,全部其餘類型的模塊,
好比圖片,css等,都須要經過對應的loader轉成js模塊。
因此在webpack中不管任何類型的資源,本質上都被當成js模塊處理。
全部的loader都是一個管道,能夠把一個loader看作是一個數據管道,
進口是一個字符串,而後通過加工,輸出另外一個字符串。
複製代碼
function transform(arr,num){
const newArr = [];
for(let i=0,len=arr.length;i < len;i=i+num){
newArr.push(arr.slice(i,i+num));
}
return newArr;
}
複製代碼
function slow(x,y,z) {
// 這裏可能會有重負載的CPU密集型工做
// ...
alert(`Called with ${XYZ}`);
return XYZ;
}
複製代碼
function memo(func){
const cache = new Map();
return function(){
// const key = [...arguments].join(',');
const key = [].join.call(arguments);
if(cache.has(key)){
return cache.get(key);
}
const res = func.apply(this, arguments);
cache.set(key, res);
return res;
}
}
memo(slow)(1,2,3);
複製代碼
前端
class Event{ constructor(){ this.pool = new Map() } broadcast(){ const [key,...rest] = [...arguments]; if(this.pool.has(key)){ const func = this.pool.get(key) func.apply(this, rest) } } addEventListenering(key, func){ this.pool.set(key,func) } removeEventListenering(key){ this.pool.delete(key) } } const ev = new Event(); ev.addEventListenering('event1',function(param){ console.log('發佈新值了',param) }) ev.broadcast('event1',1000); //發佈新值了 1000 ev.broadcast('event1',2000); //發佈新值了 2000 ev.broadcast('event1',3000); //發佈新值了 3000 ev.removeEventListenering('event1'); ev.broadcast('event1',3000); 複製代碼複製代碼
function A() {
this.a = 1;
}
A.prototype.b = 1;
const a = new A();
console.log(a.a);
console.log(a.b);
const b = new A();
b.__proto__.a = 2;
A.prototype.b = 2;
console.log(a.a);
console.log(a.b);
複製代碼
1 1 1 2複製代碼
var name = '小紅';
var obj = {
name: '小明',
sayName() {
console.log(`${this.name}`);
},
};
var sayName = () => {
console.log(`${this.name}`);
};
var fn = obj.sayName;
sayName();
obj.sayName();
sayName.call(obj);
obj.sayName.call(this);
fn();
複製代碼
小紅 小明 小紅 小紅 小紅複製代碼
new Promise((resolve) => {
console.log(3);
resolve();
}).then(() => {
onsole.log(4);
});
setTimeout(() => {6
console.log(2);
}, 0);
Promise.resolve().then(() => {
console.log(5);
});
console.log(1);
複製代碼
3 1 4 5 2複製代碼