每日up

2018-7-28

1.談談JavaScript的垃圾回收機制

因爲字符串、對象和數組沒有固定大小,全部當他們的大小已知時,才能對他們進行動態的存儲分配。JavaScript程序每次建立字符串、數組或對象時,解釋器都必須分配內存來存儲那個實體。只要像這樣動態地分配了內存,最終都要釋放這些內存以便他們可以被再用,不然,JavaScript的解釋器將會消耗完系統中全部可用的內存,形成系統崩潰。 如今各大瀏覽器一般用採用的垃圾回收有兩種方法:標記清除、引用計數。javascript

  • 標記清除:這是javascript中最經常使用的垃圾回收方式:是當變量進入環境時,將這個變量標記爲「進入環境」。當變量離開環境時,則將其標記爲「離開環境」。標記「離開環境」的就回收內存。工做流程:
    • 垃圾回收器,在運行的時候會給存儲在內存中的全部變量都加上標記。
    • 去掉環境中的變量以及被環境中的變量引用的變量的標記。
    • 再被加上標記的會被視爲準備刪除的變量。
    • 垃圾回收器完成內存清除工做,銷燬那些帶標記的值並回收他們所佔用的內存空間。
  • 另外一種不太常見的垃圾回收策略是引用計數:工做原理:跟蹤記錄每一個值被引用的次數。工做流程:
    • 聲明瞭一個變量並將一個引用類型的值賦值給這個變量,這個引用類型值的引用次數就是1。
    • 同一個值又被賦值給另外一個變量,這個引用類型值的引用次數加1.
    • 當包含這個引用類型值的變量又被賦值成另外一個值了,那麼這個引用類型值的引用次數減1.
    • 當引用次數變成0時,說明沒辦法訪問這個值了。
    • 當垃圾收集器下一次運行時,它就會釋放引用次數是0的值所佔的內存。

可是用這種方法存在着一個問題,下面來看看代碼:vue

function problem() {
    var objA = new Object();
    var objB = new Object();
    objA.someOtherObject = objB;
    objB.anotherObject = objA;
}
複製代碼

在這個例子中,objA和objB經過各自的屬性相互引用;也就是說這兩個對象的引用次數都是2。在採用引用計數的策略中,因爲函數執行以後,這兩個對象都離開了做用域,函數執行完成以後,objA和objB還將會繼續存在,由於他們的引用次數永遠不會是0。這樣的相互引用若是說很大量的存在就會致使大量的內存泄露。java

  • 什麼狀況會引發內存泄漏?

    雖然有垃圾回收機制可是咱們編寫代碼操做不當仍是會形成內存泄漏。數組

    • 意外的全局變量引發的內存泄漏。緣由:全局變量,不會被回收。解決:使用嚴格模式避免。
    • 閉包引發的內存泄漏。緣由:閉包能夠維持函數內局部變量,使其得不到釋放。解決:將事件處理函數定義在外部,解除閉包,或者在定義事件處理函數的外部函數中,刪除對dom的引用。
    • 沒有清理的DOM元素引用。緣由:雖然別的地方刪除了,可是對象中還存在對dom的引用,解決:手動刪除。
    • 被遺忘的定時器或者回調。緣由:定時器中有dom的引用,即便dom刪除了,可是定時器還在,因此內存中仍是有這個dom。解決:手動刪除定時器和dom。
    • 子元素存在引用引發的內存泄漏。緣由:div中的ul li 獲得這個div,會間接引用某個獲得的li,那麼此時由於div間接引用li,即便li被清空,也仍是在內存中,而且只要li不被刪除,他的父元素都不會被刪除。解決:手動刪除清空

2018-7-25

1.談談Cookie的弊端

  • Cookie數量和長度的限制。每一個domain最多隻能有20條cookie,每一個cookie長度不能超過4KB,不然會被截掉
  • 安全性問題。若是cookie被人攔截了,那人就能夠取得全部的session信息。即便加密也與事無補,由於攔截者並不須要知道cookie的意義,他只要原樣轉發cookie就能夠達到目的了。
  • 有些狀態不可能保存在客戶端。例如,爲了防止重複提交表單,咱們須要在服務器端保存一個計數器。若是咱們把這個計數器保存在客戶端,那麼它起不到任何做用

2.淺拷貝和深拷貝的區別

JavaScript的數據類型分爲兩大種:

  • 基本類型:Undefined、Null、Boolean、Number 和 String,這5中基本數據類型能夠直接訪問,他們是按照值進行分配的,存放在棧(stack)內存中的簡單數據段,數據大小肯定,內存空間大小能夠分配。
  • 引用類型:即存放在堆(heap)內存中的對象,變量實際保存的是一個指針,這個指針指向另外一個位置。每一個空間大小不同,要根據狀況開進行特定的分配。

stack(棧)爲自動分配的內存空間,它由系統自動釋放;而heap(堆)則是動態分配的內存,大小不定也不會自動釋放。當咱們須要訪問引用類型(如對象,數組,函數等)的值時,首先從棧中得到該對象的地址指針,而後再從堆內存中取得所需的數據。

基本類型與引用類型最大的區別實際就是傳值與傳址的區別。

var a = [1,2,3,4,5];
    var b = a;
    var c = a[0];
    alert(b);//1,2,3,4,5
    alert(c);//1
    //改變數值        
    b[4] = 6;
    c = 7;
    alert(a[4]);//6
    alert(a[0]);//1
複製代碼

JS 中的淺拷貝與深拷貝,只是針對複雜數據類型(Object,Array)的複製問題。淺拷貝與深拷貝均可以實如今已有對象上再生出一份的做用。可是對象的實例是存儲在堆內存中而後經過一個引用值去操做對象,由此拷貝的時候就存在兩種狀況了:拷貝引用和拷貝實例,這也是淺拷貝和深拷貝的區別。瀏覽器

深複製和淺複製最根本的區別在因而否是真正獲取了一個對象的複製實體,而不是引用安全

  • 淺拷貝:淺拷貝是拷貝引用,拷貝後的引用都是指向同一個對象的實例,彼此之間的操做會互相影響
  • 深拷貝:在堆中從新分配內存,而且把源對象全部屬性都進行新建拷貝,以保證深拷貝的對象的引用圖不包含任何原有對象或對象圖上的任何對象,拷貝後的對象與原來的對象是徹底隔離,互不影響

淺拷貝 :所謂的淺複製,只是拷貝了基本類型的數據,而引用類型數據,複製後也是會發生引用,咱們把這種拷貝叫作「(淺複製)淺拷貝」

var a = {
  key1:"11111"
}
function Copy(p) {
  var c = {};
  for (var i in p) {
   c[i] = p[i];
  }
  return c;
}
a.key2 = ['小輝','小輝'];
var b = Copy(a);
b.key3 = '33333';
alert(b.key1);     //1111111
alert(b.key3);    //33333
alert(a.key3);    //undefined
b.key2.push("大輝");
alert(b.key2); //小輝,小輝,大輝
alert(a.key2); //小輝,小輝,大輝
複製代碼

緣由是key1的值屬於基本類型,因此拷貝的時候傳遞的就是該數據段;可是key2的值是堆內存中的對象,因此key2在拷貝的時候傳遞的是指向key2對象的地址,不管複製多少個key2,其值始終是指向父對象的key2對象的內存空間。bash

深拷貝 :而深複製的話,咱們要求複製一個複雜的對象,那麼咱們就能夠利用遞歸的思想來作,及省性能,又不會發生引用。

function Copy(p, c) {
  var c = c || {};
  for (var i in p) {
    if (typeof p[i] === 'object') {
      c[i] = (p[i].constructor === Array) ? [] : {};
      Copy(p[i], c[i]);
    } else {
      c[i] = p[i];
    }
  }
  return c;
}    
a.key2 = ['小輝','小輝'];
var b={};
b = Copy(a,b);        
b.key2.push("大輝");
alert(b.key2);    //小輝,小輝,大輝
alert(a.key2);    //小輝,小輝
複製代碼

2018-7-19

1.用javascipt寫一個方法,模擬實現bind方法

來源https://blog.csdn.net/daimomo000/article/details/72897035服務器

Function.prototype.bind2 = function (context) {

    if (typeof this !== "function") {
      throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};

    var fbound = function () {
        self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
    }

    fNOP.prototype = this.prototype;
    fbound.prototype = new fNOP();

    return fbound;

}
複製代碼

2.js哪些操做會實行隱式轉換

  • 1 對象和布爾值比較

    對象和布爾值進行比較時,對象先轉換爲字符串,而後再轉換爲數字,布爾值直接轉換爲數字cookie

[] == true; //false []轉換爲字符串'',而後轉換爲數字0,true轉換爲數字1,因此爲false
複製代碼
  • 2 對象和字符串比較

    對象和字符串進行比較時,對象轉換爲字符串,而後二者進行比較。session

[1,2,3] == '1,2,3' // true [1,2,3]轉化爲'1,2,3',而後和'1,2,3', so結果爲true;
複製代碼
  • 3 對象和數字比較

    對象和數字進行比較時,對象先轉換爲字符串,而後轉換爲數字,再和數字進行比較。

[1] == 1; // true `對象先轉換爲字符串再轉換爲數字,兩者再比較 [1] => '1' => 1 因此結果爲true
複製代碼
  • 4 字符串和數字比較

    字符串和數字進行比較時,字符串轉換成數字,兩者再比較。

'1' == 1 // true
複製代碼
  • 5 字符串和布爾值比較

    字符串和布爾值進行比較時,兩者所有轉換成數值再比較。

'1' == true; // true
複製代碼
  • 6 布爾值和數字比較

    布爾值和數字進行比較時,布爾轉換爲數字,兩者比較。

true == 1 // true
複製代碼

任意兩種類型比較時,若是不是同一個類型比較的話,則按如圖方式進行相應類型轉換,如對象和布爾比較的話,對象 => 字符串 => 數值 布爾值 => 數值。

3.瀏覽器標準模式和怪異模式之間的區別是什麼

在HTML與CSS的標準化未完成以前,各個瀏覽器對於HTML和CSS的解析有各自不一樣的實現,而有不少舊的網頁都是按照這些非標準的實現去設計的。在HTML與CSS標準肯定以後,瀏覽器一方面要按照標準去實現對HTML與CSS的支持,另外一方面又要保證對非標準的舊網頁設計的後向兼容性。所以,現代的瀏覽器通常都有兩種渲染模式:標準模式和怪異模式。在標準模式下,瀏覽器按照HTML與CSS標準對文檔進行解析和渲染;而在怪異模式下,瀏覽器則按照舊有的非標準的實現方式對文檔進行解析和渲染。

區別

  • 盒模型:IE下標準模式爲:content+padding+border+margin。怪異模式下爲:content+margin(padding,border包含在content寬高中)
  • 怪異模式中IE6/7/8都不識別!important聲明
  • 設置行內元素寬高,標準模式下不生效,怪異模式下生效
  • margin:0 auto,在標準模式下會水平居中,怪異模式下不會。

4.聲明式函數和表達式函數的區別

定義函數有兩種方式:函數聲明和函數表達式。

函數聲明
function functionName(arg0,arg1){
//函數體
}
複製代碼
函數表達式
a();
function a(){alert("a");}
//a
複製代碼
  • 函數聲明中函數名是必須的,函數表達式中則是可選的
  • 用函數聲明定義的函數,函數能夠在函數聲明以前調用,而用函數表達式定義的函數則只能在聲明以後調用。

2018-7-18

1.實現函數fn(2)(4) == 8

function fn(x){
    return function(y){
        return x*y
    }
}
複製代碼

2.vue共有多少個生命週期函數

  • beforeCreate 在實例初始化以後,數據觀測 (data observer) 和 event/watcher 事件配置以前被調用
  • created 在實例建立完成後被當即調用。在這一步,實例已完成如下的配置:數據觀測 (data observer),屬性和方法的運算,watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
  • beforeMount 在掛載開始以前被調用:相關的 render 函數首次被調用
  • mounted el被新建立的 vm.el 替換,並掛載到實例上去以後調用該鉤子。若是 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.el 也在文檔內。
  • beforeUpdate 數據更新時調用,發生在虛擬 DOM 打補丁以前。這裏適合在更新以前訪問現有的 DOM,好比手動移除已添加的事件監聽器。
  • updated 因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。
  • activated keep-alive 組件激活時調用。
  • deactivated keep-alive 組件停用時調用。
  • beforeDestory 實例銷燬以前調用。在這一步,實例仍然徹底可用。
  • destoryed Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
  • errorCaptrued

3.原型和原型鏈

  • 原型鏈的原理:
__proto__ = constructor.prototype
複製代碼

只有函數纔有prototype屬性而且能夠訪問到,可是對象實例不具備該屬性,只有一個內部的不可訪問的__proto__屬性。__proto__是對象中一個指向相關原型的神祕連接。按照標準,__proto__是不對外公開的,也就是說是個私有屬性,可是Firefox的引擎將他暴露了出來成爲了一個共有的屬性,咱們能夠對外訪問和設置。

  • 原型對象

每建立一個函數都會有一個prototype屬性,這個屬性是一個指針,指向一個對象(經過該構造函數建立實例對象的原型對象)。原型對象是包含特定類型的全部實例共享的屬性和方法。原型對象的好處是,可讓全部實例對象共享它所包含的屬性和方法。(原型對象屬於普通對象。Function.prototype是個例外,它是原型對象,卻又是函數對象,做爲一個函數對象,它又沒有prototype屬性。)

  • 原型鏈

在JavaScript 中,每一個對象都有一個指向它的原型(prototype)對象的內部連接。這個原型對象又有本身的原型,直到某個對象的原型爲 null 爲止(也就是再也不有原型指向),組成這條鏈的最後一環。這種一級一級的鏈結構就稱爲原型鏈(當試圖訪問一個對象的屬性時,它不只僅在該對象上搜尋,還會搜尋該對象的原型,以及該對象的原型的原型,依此層層向上搜索,直到找到一個名字匹配的屬性或到達原型鏈的末尾。)

原型對象(Person.prototype)是 構造函數(Person)的一個實例。

function Animal(){  
  this.type = "animal";  
}  
Animal.prototype.getType = function(){  
  return this.type;  
}  
function Dog(){  
  this.name = "dog";  
}  
Dog.prototype = new Animal();    
Dog.prototype.getName = function(){  
  return this.name;  
}   
var xiaohuang = new Dog();  
//原型鏈關係  
xiaohuang.__proto__ === Dog.prototype  
Dog.prototype.__proto__ === Animal.prototype  
Animal.prototype.__proto__ === Object.prototype  
Object.prototype.__proto__ === null

複製代碼

4.vue每一個生命週期的做用(同上2)

5.position有幾個屬性,做用

  • absolute: 生成絕對定位的元素,相對於 static 定位之外的第一個父元素進行定位。元素的位置經過 "left", "top", "right" 以及 "bottom" 屬性進行規定。
  • fixed :生成絕對定位的元素,相對於瀏覽器窗口進行定位。元素的位置經過 "left", "top", "right" 以及 "bottom" 屬性進行規定。
  • relative: 生成相對定位的元素,相對於其正常位置進行定位。所以,"left:20" 會向元素的 LEFT 位置添加 20 像素。
  • static :默認值。沒有定位,元素出如今正常的流中(忽略 top, bottom, left, right 或者 z-index 聲明)
  • inherit: 規定應該從父元素繼承 position 屬性的值。
  • unset:名如其意,unset 關鍵字咱們能夠簡單理解爲不設置。其實,它是關鍵字 initial 和 inherit 的組合。什麼意思呢?也就是當咱們給一個 CSS 屬性設置了 unset 的話:若是該屬性是默認繼承屬性,該值等同於 inherit, 若是該屬性是非繼承屬性,該值等同於 initial
  • sticky: 設置了sticky的元素,在屏幕範圍(viewport)時該元素的位置並不受到定位影響(設置是top、left等屬性無效),當該元素的位置將要移出偏移範圍時,定位又會變成fixed,根據設置的left、top等屬性成固定位置的效果。

(當元素在容器中被滾動超過指定的偏移值時,元素在容器內固定在指定位置。亦即若是你設置了top: 50px,那麼在sticky元素到達距離相對定位的元素頂部50px的位置時固定,再也不向上移動。)

sticky屬性生效的條件有如下兩點:

- 是元素自身在文檔流中的位置
- 一個是該元素的父容器的邊緣
複製代碼
相關文章
相關標籤/搜索