js基礎知識梳理

從問題入手

學習知識基礎是關鍵。在此記錄關鍵問題,不斷豐富。僅供本身學習。前端

問題

  • js內存分幾類?分別用來存放什麼?
  • 全局做用域和私有做用域
  • 內存釋放
  • 什麼叫預解釋?
  • 全局變量和私有變量
  • 函數執行基本順序
  • 代碼執行變量獲取順序
  • 解釋閉包
  • this的指向
  • 前端常接觸的設計模式
  • var n1 = new Number和var n2 = 1有什麼不一樣?var a1 = new Array和var a2 = []有什麼不一樣?
  • 解釋一下js的原型鏈

  • js內存分幾類?分別用來存放什麼?

answer:js分爲棧內存和堆內存設計模式

堆內存用來存放引用數據類型的具體內容,object類型存儲key value;function類型用來存放函數內容的字符串數組

棧內存用來提供一個js代碼執行的環境。全局做用域和私有做用域都屬於棧內存。瀏覽器

  • 全局做用域和私有做用域?

answer:bash

全局做用域:瀏覽器一打開就建立,瀏覽器關閉時才銷燬。 私有做用域:函數執行才產生私有做用域。閉包

  • 內存釋放?

answer:app

堆內存釋放:引用數據類型定義的時候開闢一個新的堆內存,該內存有個引用地址。若是存在變量引用該地址,則內存被佔用不可銷燬。若想釋放,則把他的內存指向null,當前堆內存沒有被佔用,則瀏覽器會在空閒時銷燬。dom

棧內存釋放:全局做用域瀏覽器一打開即建立,關閉才銷燬。私有做用域,函數執行時產生,私有做用域的代碼執行完了,則當前做用域被銷燬。函數

可是,當前私有做用域的部份內容被當前做用域以外的內容佔用了,當前做用域不能銷燬學習

  1. 函數執行返回一個引用數據類型的值,而且在函數外被接收了。這種狀況行程的私有做用域不會被銷燬,好比返回一個函數、對象、數組、則該堆內存沒法釋放,與此同時,執行該堆內存的執行棧內存也沒法釋放。可是返回數字,字符串,布爾值,則直接返回值,函數執行產生的私有做用域執行一次銷燬一次。
  2. 私有做用域中進行dom事件綁定,由於dom事件綁定,則該私有做用域也不能釋放(dom綁定至關於返回一個函數,和狀況1本質相同)。
  3. 函數執行返回的函數並無被其他變量接收,可是會緊接着執行一次,則該內存不會當即銷燬,在執行完畢後再銷燬。
function fn(){
    var num = 100;
    return function(){
        
    }
}
fn()()
複製代碼
  • 什麼叫預解釋?

answer:也叫變量提高。在當前做用域中,js代碼執行以前,瀏覽器首先會把帶var 和 function 的進行提早聲明或定義。(var 聲明 function 聲明+定義)

預解釋只發生在當前做用域下,開始只對window下(全局做用域)下預解釋,函數執行時對(私有做用域)下進行預解釋。全局和私有做用域都存在預解釋。

  • 全局變量和私有變量?

answer:

全局變量:全局做用域下定義的變量(全局下預解釋)

私有變量:私有做用域中聲明的變量 和 函數的形參。

  • 函數執行基本順序?

answer:

  1. 生成一個新的私有做用域
  2. 若是有形參,先形參賦值
  3. 在私有做用域中進行預解釋
  4. 在私有做用域中從上到下執行代碼
  • 函數執行變量獲取順序?

answer:

  1. 先肯定私有變量中是否存在(形參+聲明的私有變量),若是有優先使用私有變量。
  2. 若是沒有則向上級做用域查找,直到window爲止。
  3. 上級做用域只和函數定義有關,和在哪執行無關。在哪一個做用域下定義的,上級做用域就是誰。
  • 解釋閉包?

answer:閉包是一種機制,函數執行時產生的私有做用域內的變量保護起來,不受外界干擾。

  • this的指向?

answer:僅表明當前行爲的執行主體

和的當前執行的環境(區域)上下文無關; 和函數在哪定義,在哪執行無關;

  1. 函數執行,函數名前面有.則.前面爲this;沒有.window爲this;
  2. 自執行函數中,this永遠指向window;
  3. 給dom元素綁定事件,當前事件觸發執行綁定方法,方法中的this執行當前dom元素。
  4. 構造函數模式中,函數體中(類中)的this中,指向當前類的一個實例。
  • 前端常接觸的設計模式 answer:
  1. 單例模式:分組編寫各自的功能模塊。
  2. 工廠模式:相同功能代碼,抽取到一個函數處理。
  3. 構造函數模式:建立類,並利用類的實例。
function Fn(){
    this.x = 100;
}
Fn.prototype.getX = function(){};
var f1 = new Fn
複製代碼
構造函數模式注意點:
1. 不須要傳參時,()能夠省略。
2. 構造函數中的this指向某個實例,可是屬性值內包含this,須要看.前面的內容。
複製代碼
function Fn(){
    this.x = 100;
    this.getX = function(){
        console.log(this.x)
    }
}
var f1 = new Fn
複製代碼
3. 構造函數裏的var只是私有變量而已,和類、實例無關。
4. 構造函數模式中,**瀏覽器默認把實例返回**,返回一個**對象數據類型**的值。若是本身在構造函數中寫return。return 基本數據類型的值,則當前實例不變。若return 引用數據類型,則當前實例爲該引用數據類型。
複製代碼
function Fn(){
    this.x = 100;
    return [1,2,3]
}
var f1 = new Fn;
console.log(f1); // [1, 2, 3]
複製代碼
  1. 原型鏈模式:在構造函數基礎上,解決屬性共有問題。
  • var n1 = new Number和var n2 = 1有什麼不一樣?var a1 = new Array和var a2 = []有什麼不一樣?

answer:

new的形式是實例建立方式,n=1是對象字面量方式。前者是標準建立實例的方式。第二種是js弱類型語言獨有的建立實例的方式。

針對引用數據類型:對象字面量,和類實例方式建立沒有不一樣。 針對基本數據類型:二者不一樣。

var n1 = new Number(1);
var n2 = 1;
typeof(n1) // object
typeof(n2) //number
n1 instanceOf Number //true
n2 instanceOf number // false
複製代碼
  • 解釋一下js的原型鏈

答:

* 全部函數數據類型,都自帶一個prototype屬性,存儲值爲對象數據類型,瀏覽器默認開闢一個堆內存
* prototype在瀏覽器環境下,擁有一個constructor屬性,指向當前類自己
* 每一個對象數據類型(普通對象,數組,正則,實例,prototype,函數),也天生自帶一個屬性__proto__。指向`當前實例所屬類的原型(prototype)`
複製代碼
  • 類的私有屬性(方法)和公有屬性(或方法)分別在哪定義?

答:

私有寫到函數體中,this.的形式定義 公有寫到prototye原型鏈中

  • 詳細列出div元素;a元素;document;window的原型鏈?

答: 爲何div元素有getElementsByClassName;可是卻沒有getElementById

  • 一個函數的多面性

答: 全部函數數據類型都是Function類的實例 全部類都是函數 每一個函數都是Object類的實例

一、普通函數 執行的時候造成私有做用域(閉包) 形參賦值 預解釋 代碼執行,執行完成後棧內存銷燬or被佔用而不能銷燬 二、類 他有本身的實例,也有一個prototype屬性指向原型 三、普通對象: 能夠有本身私有屬性(name,length,等等),也有__proto__指向Funtion的prototype 三者沒有必然聯繫,每種角色,不混用!!!

特殊記憶: Function.prototype是函數數據類型的,可是相關操做和對象如出一轍。-->anonymous(匿名函數)

  • call的做用

call是存在於Function.prototype上的屬性方法

call的做用在於:改變this關係

call執行:1)讓fn中this變爲obj ;2)再把fn中的內容執行完成。

概念化call原理以下:

// Function.prototype.call = mycall function (context) {
    // 一、讓fn中this 關鍵字變成context的值
    // eval(this.toString().replace('this', 'context'));
    // 二、讓fn執行
    // this();
// }
   // call 方法執行
   obj = {};
   fn.call(obj)
複製代碼

call的測試題,以下四個輸出結果

function fn1() {
    console.log(1);
}

function fn2() {
    console.log(2);
}
fn1.call(fn2); 
fn1.call.call(fn2); 
Function.prototype.call(fn1);
Function.prototype.call.call(fn1);
複製代碼

結果:

1;2;undefined;1;

Function.prototype.call(fn1);// Function.prototype爲空函數,this指向fn1,空函數執行,獲得undefined

  • 嚴格模式和非嚴格模式下call執行的不一樣點
"use strict"
function fn(num1, num2) {
    console.log(num1 + num2);
    console.log(this);
}
var obj = {
    'key': 'value'
};
fn(100, 200);
fn.call(100, 200);
fn.call(obj, 100, 200);
fn.call(); // this->window  嚴格模式下 undefined
fn.call(null); // this->window 嚴格模式下 null
fn.call(undefined); // this->window 嚴格模式下 undefined
複製代碼
  • call apply bind 三者之間關係

call,apply做用相同,包含改變this指向+執行。不一樣的是,call接收參數,apply接收數組做爲參數。

bind,預先改變this執行,但不執行。預處理的性質。ie6-8不兼容

相關文章
相關標籤/搜索