2018前端面試總結js部分【中】

隴錦發表於2018-06-24

定義函式的方法

1.
        語法:function 函式名(引數1[,引數2]……){
        	函式體;
        	[return];   //返回值
        }
        function fx() {
            
        }
        
        function () {
            
        }  //匿名函式

2.字面量 
        var fn=function(){
        
        }
        
3.通過函式物件方式

        var x=new function () {
                
        }
複製程式碼

函式的呼叫

  • 這裡的this指向window
//1、函式名();
     function getSum() {
        console.log(this) //window
     }
     getSum()
     
//2、自呼叫(function(){})()
           
     (function() {
        console.log(this) //window
     })();
     
//3、變數名()     
     var getSum=function() {
        console.log(this) //window
     };
     getSum()
複製程式碼

建立例項的方法

//1.json方法
    
    let obj={
        name:"張山",
        age:"11",
        call:function(){
            alert(1)
        }
    };
    obj.call();
    
//2.建構函式方法

    function Obj(){
    		this.name = "張三",
    		this.sex = "男",
    		this.phone = 17603514842,
    		this.call = function(){
    			alert(1);
    		}
    	}
    	let obj = new Obj();
    	obj.call();    
    	
//3.object方法

    	var obj = new Object();
    	obj.name = "張三";
    	obj.sex = "男";
    	obj.call = function(){
    		alert(this.name);
    	};
    	obj.call();
複製程式碼

JavaScript的資料型別

  • string number boolean null underfind object typeof (7種)

什麼是閉包,閉包有什麼缺點 什麼情況下用閉包

  • 閉包就是函式巢狀函式,可以理解為定義在函式內部的函式,本質上閉包是函式內部和外部連線的橋樑,但如果父函式定義的變數沒有被子函式引用就不叫閉包
  • 閉包讓函式的變數都儲存在記憶體中,記憶體消耗變大。使用不當會造成記憶體洩漏。
  • 用途:讀取函式內部變數 讓變數儲存到記憶體中 設定私有變數和方法

函式過載 以及解析順序

        var m= 1, j = k = 0; 
        function add(n) { 
            return n = n+1; 
      } ;
        y = add(m); 
        function add(n) { 
            return n = n + 3; 
        } ;
    z = add(m); 
複製程式碼
  • 以上程式碼都會輸出4,js中沒有函式過載的概念,由於定義了連個相同的函式,所以後面的會覆蓋前面的
    所以呼叫add結果都是一樣的因此真正到執行程式碼的時候,也就是第一次呼叫add(),輸出的當然是4,第二次執行add()同樣輸出4.

js函式呼叫時加括號和不加括號的區別.不加括號相當於把函式程式碼賦給等號左邊,加括號是把函式返回值賦給等號左邊

    var color='green';
    var text={
        color:'blue',
        getColor:function() {
          var color='red';
          alert(this.color)
        }
    };
    var getColor=text.getColor;
    getColor();
    text.getColor();
    //結果為 green blue
複製程式碼

關於this指標

  • 直接呼叫的話 this指向window物件(這裡如果在函式內部宣告一個name也指向的window物件)
    
   var name='張三';
   function sayname() {
     console.log(this.name)
   };
   sayname();
複製程式碼
  • 物件函式呼叫 this指向物件本身
    var name='Bob';
    function sayName(){
        console.log(this.name);
    };
    var object={'name':'vicky'};
    object.sayName=sayName;          //sayName沒有寫成sayName(),表示不是執行函式,而是將sayName的指標賦值給object.sayName
    object.sayName();               //由於物件函式呼叫方法,this指向物件本身,所以輸出:'vicky'
    sayName();                     //由於全域性環境呼叫sayName()等同於window.sayName();輸出:'Bob'
複製程式碼
  • 建構函式呼叫 this指標指向新建立的物件
    function object(name){
        this.name=name;
        console.log(this);      //由於this指向新建立的物件本身,輸出:Object { name: "vikcy" }
        console.log(this.name);  //輸出:"vicky"
    }
    var myObject=new Object('vicky');  //由於this指向新建立的物件本身
複製程式碼

JavaScript原型 原型鏈

  • 每個物件都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個物件的屬性時,
    如果這個物件內部不存在這個屬性,那麼他就會去prototype裡找這個屬性,這個prototype又會有自己的prototype,
    於是就這樣一直找下去,也就是我們平時所說的原型鏈的概念。

JavaScript有幾種型別的值?

  • 棧:原始資料型別(Undefined,Null,Boolean,Number、String)
  • 堆:引用資料型別(物件、陣列和函式) 兩種型別的區別是:儲存位置不同; 原始資料型別直接儲存在棧(stack)中的簡單資料段,佔據空間小、大小固定,屬於被頻繁使用資料,所以放入棧中儲存; 引用資料型別儲存在堆(heap)中的物件,佔據空間大、大小不固定。如果儲存在棧中,將會影響程式執行的效能;引用數
    據型別在棧中儲存了指標,該指標指向堆中該實體的起始地址。當直譯器尋找引用值時,會首先檢索其在棧中的地址,取
    得地址後從堆中獲得實體

任何物件轉為布林值,都為得到 true(切記!在JS中,只有 0,-0,NaN,"",null,undefined 這六個值轉布林值時,結果為 false)

    
   var x = new Boolean(false);
   if (x) {
     alert('hi');
   }
   var y = Boolean(0);
   if (y) {
     alert('hello'); 
   }
   
   //結果只會顯示 hi

複製程式碼

變數提升

  • 在某作用域,宣告變數語句會預設解析為在該作用域的最開始就宣告瞭。
    var a=5;
    function foo() {
      a=2;
      console.log(a);
      var a;
    }
    foo();
    //結果會輸出2
複製程式碼
  • 我們可以看到,var a;語句並沒有重新整理a的值,因為解析編譯的時候,’var a;’被提前了.所以我們看的a是內部變數a而不是外面已賦值的5。
  var a=5;
  function foo() {
    console.log(a);
    var a=1;
  }
  foo();
  //結果輸出underfind
複製程式碼
  • 由於變數提升的原因a已經宣告,所以沒有輸出我們再外部宣告的5,但是a=1;並沒有被提前執行.所以變數提升這個概念,只適用於宣告變數的
    語句,而變數賦值的語句並不能被提前
    foo();
    function foo(){
        console.log(1);
    }
    //TypeError: foo is not a function
複製程式碼
  • 這裡的foo被提升了,所以這裡並沒有發生ReferenceError,但是這個時候foo並沒有被賦值,所以發生了TypeError。這段程式碼經過提升後是這樣的:
    var foo;
    foo();
    foo=function fooo() {
      console.log(1)
    }
複製程式碼
  • 我們習慣將‘var a=5’看做一條宣告。其實這裡兩條語句的簡寫,‘var a’和‘a = 3’,並且其實這兩條語句是兩個不同型別的語句,是由兩個不同
    的元件完成的。前一句是在編譯階段執行,後一句是在執行階段執行。所以,不管’var a’寫在哪裡,都會在程式碼本身被執行之前處理。這一過程很像
    是程式碼的一個移動過程,所以被大家稱為“變數提升”。

瀏覽器從輸入url到載入完成 都發生了什麼

1、瀏覽器位址列輸入url

2、瀏覽器會先檢視瀏覽器快取--系統快取--路由快取,如有存在快取,就直接顯示。如果沒有,接著第三步

3、域名解析(DNS)獲取相應的ip

4、瀏覽器向伺服器發起tcp連線,與瀏覽器建立tcp三次握手

5、握手成功,瀏覽器向伺服器傳送http請求,請求資料包

6、伺服器請求資料,將資料返回到瀏覽器

7、瀏覽器接收響應,讀取頁面內容,解析html原始碼,生成DOM樹

8、解析css樣式、瀏覽器渲染,js互動

常見的瀏覽器核心

谷歌:-webkit- 火狐:-moz- ie:-ms- 歐鵬:-o- qq瀏覽器:雙核心 -webkit- -ms-

節點操作

  • 建立節點
      createDocumentFragment() //建立一個DOM片段
       createElement() //建立一個具體的元素
       createTextNode() //建立一個文字節點

  • 新增、移除、替換、插入
    appendChild() //新增
      removeChild() //移除
      replaceChild() //替換
      insertBefore() //插入

  • 查詢
    getElementsByTagName() //通過標籤名稱
      getElementsByName() //通過元素的Name屬性的值
      getElementById() //通過元素Id,唯一性

作用域

  • 每個函式都有一個作用域,比如我們建立了一個函式,函式裡面又包含了一個函式,那麼現在就有三個作用域,這樣就形參了一個作用域鏈
  • 特點: 先在自己的變數範圍中查詢,如果找不到,就會沿著作用域鏈網上找。

相關文章