JS第一週學習筆記整理

JS正式課第一週筆記整理

  • webstorm : 代碼編輯器
  • 瀏覽器: 代碼解析器;
  • Git : 是一個工具;用於團隊協做開發項目管理代碼的工具;在工做中用git、svn
  • svn : 集中式;
  • 集中式:須要一箇中央服務器;每次開發前須要從中央服務器把最新的代碼拉取下來,而後進行開發;而且須要網絡;
  • git : 分佈式;
  • 分佈式:每一個人的電腦都是一箇中央服務器;不須要網絡也能夠進行提交代碼;

DOS命令

  • 1.按着shift右鍵,在此處打開powerShell
  • 2.找到相應的文件夾,直接輸入cmd,按回車;
  • window+r : 輸入cmdjava

    切換磁盤路徑
    • cd + 文件夾名字: 打開相應的路徑
    • cd ../ : 回到上一級
    • cd / : 回到跟路徑;
    • mkdir + 文件名字 : 建立文件夾
    • cls : 清除全部的命令

    Git

    配置Git用戶名和密碼
  • git config --global user.email "郵箱"
  • git config --global user.name "用戶名"android

Git的簡單命令
  • git init : 初始化一個git 倉庫(生產.git文件)
  • git add . : 把全部文件提交到暫存區
  • git add [文件名]:推送指定的文件到暫存區
  • git commit -m"註釋" : 把代碼提交到歷史區;(推送到歷史區以後Git會自動分配一個版本號xxxxxx,根據版本號能夠回到任何一次修改的位置)
  • git status:查看文件狀態;若是文件只存在本地,不在暫存區,那麼顏色是紅色,若是文件在暫存區尚未提交到歷史區,那麼顏色是綠色
  • 本地代碼- ->暫存區- ->歷史區git

    本地倉庫與遠程倉庫通訊
  • git remote add origin(倉庫名) url地址:將本地倉庫與遠程倉庫創建鏈接
  • git remote -v:查看本地倉庫和遠程倉庫關聯狀態
  • git push origin(與創建鏈接時的倉庫名同樣) master(主分支名):將歷史區內容推送到遠程倉庫
  • git config --list:查看本地配置環境
  • 輸入用戶名和密碼es6

    推送過程(詳細步驟)
    本地操做
  • ① git init(初始化git倉庫)
  • ② git add .(將文件推送到暫存區)
  • ③ git status(查看文件狀態)
  • ④ git commit -m "註釋"(將代碼提交到歷史區,並添加註釋)github

    遠程倉庫操做
  • git remote add origin(倉庫名) url地址
  • git remote -v
  • git push origin(倉庫名) master
    Alt textweb

    推送復原過程

    Alt text

    拉取克隆過程(詳細步驟)
  • git clone 倉庫地址url:這裏已是一個git倉庫,而且已經和遠程創建和鏈接
  • git pull origin master:拉取遠程倉庫代碼
    Alt text設計模式

GitHub

  • GitHib:是一個開源網站,能夠供你們分享代碼 插件和框架
  • 把本地的代碼提交到遠程倉庫(GitHub)
  • 讓本地倉庫和遠程倉庫進行綁定數組

    做用域

    做用域:代碼執行的空間環境 ===棧內存瀏覽器

    瀏覽器的渲染機制:先造成一個DOM樹和CSS樹,最後兩個樹合成render樹

    全局做用域 : 當打開瀏覽器時,瀏覽器會造成一個全局的做用域,給當前代碼提供運行環境的;而且存儲基本數據類型值;
    • 存儲基本數據類型值
    • 基本數據類型存儲到棧內存中,全局做用域是最大的一個棧內存
    • window是全局中最大的一個對象,存儲了大量的內置屬性

    私有做用域:一個函數執行的時候就會造成一個私有做用域,函數執行完成(或關閉瀏覽器)就銷燬
    塊級做用域:ES6新增的,除了私有做用域和對象之外全部被一個{}包裹起來的,(三個判斷,三個循環)eval("({a:1})")、for 循環中用let ,會造成父做用域;每循環一次,都會造成一個子做用域;在子做用域中會把當前的i進行保存

全局變量:在全局做用域下定義的變量
  • 會給window新增一個鍵值對
  • 全局下定義的函數至關於給window新增鍵值對,屬性名是函數,屬性值是整個函數
私有變量:
  • 在函數體中被var 、function、const、let聲明
  • 函數的形參也是私有變量

    性能優化
//1-
function fn(){
//傳入任意參數求和
    var total = 0;
    var len = arguments.length;
//(var i = 0;i<arguments.lenth;i++)
    for(var i = 0;i<len;i++){
        var cur = arguments[i];
        if(!isNaN(cur)){
        //total += arguments[i];
        total += cur;
        }
    }
}
//2- in 方法用於檢測對象中是否有該屬性
function fn(){}
console.log('fn' in window);//true
//'fn'必須加引號,不叫引號就是這個變量對應的值

//3-
var a,b,fn = function(){
    var a = b = 10;
    //(var a = b = 10;-->var a = 10;b = 10;)
    //a變成了局部變量沒法修改外部,b是全局變量,修改了外部
}
fn();
console.log(a,b);//undefined 10

變量提高

http://www.javashuo.com/article/p-ujytkfgn-hv.html

https://blog.csdn.net/longwenjunjie/article/details/48163293

變量提高的定義

變量提高:在做用域造成以後代碼執行以前,將全部帶var和function關鍵字的變量提早聲明或定義

JS能夠在瀏覽器中農運行 是由於瀏覽器給JS提供了賴以生存的環境,這個環境就是做用域

  • var:只是提早聲明;默認值是undefined
  • function:既聲明又定義
  • debugger:打斷點

造成做用域-變量提高-代碼從上到下執行

變量提高的特殊狀況
  • 無論條件是否成立,都要進行變量提高
  • 條件判斷中的函數,在條件判斷以前,帶var和帶function都只是聲明不定義
  • 當條件成立以後,第一件事就是給函數複製;
  • 條件不成立,判斷體就不執行,結合ES6的塊級做用域
  • 若是不帶var直接賦值就至關於給window直接添加了一個屬性 而且給它賦值
  • var就至關於子安全局做用域下增長了一個屬性,還給全局對象window增長了一個屬性
  • 注意: 帶var 的能夠不賦值,可是也至關於給全局對象window增長了一個屬性. 不帶var的必需要賦值,不然就會去找全局對象window上是否有這個屬性,沒有這個屬性就會報錯.

    • 用逗號分隔的表示連var;如:var a = 1,b = 2,c = 3;
    • 用分號(分號表明代碼段)來分隔的,前面帶var的屬於變量,不帶var的至關於給全局對象window添加了屬性;如:var a = 1;b = 2;c = 3;
    • 連等 帶var的是一個變量,其餘的不帶var的就至關於給全局對象window添加了屬性
  • ==變量提高只發生在=左邊==
  • ==return後面的內容不進行變量提高 可是下面的 代碼要進行變量提高==
function f3(){
    console.log(f4());//打印f3函數體中的內容
    console.log(f2());//報錯f2沒有進行變量提高
    return function f2(){
    //return 後面的內容不進行變量提高 可是下面的代碼要進行變量提高
    }
    function f4(){
        console.log(f3);
    }
}
f3();
var a = [1];
b = a;
b[1] = 'a';//b = [1,'a']
console.log(a);//[1,'a'] b指向了a的地址,修改的時候修改了地址中的屬性以及屬性值
  • 變量名重複:再也不進行聲明,可是要從新定義 (函數名跟變量名重複取函數名、函數名和函數名重複會覆蓋)
  • 函數當作參數的時候,不進行變量提高
  • 匿名函數不進行變量提高
  • 自執行函數不會進行變量提高
  • let const聲明的變量不進行變量提高

    函數的定義與執行

  • 定義的三步曲:
  • 開闢新的堆內存
  • 存儲代碼字符串
  • 返回內存空間地址
  • 函數執行過程:
  • 首先會造成一個私有做用域,開闢一個棧內存
  • 形參賦值
  • 變量提高
  • 代碼從上到下執行
  • 做用域是否銷燬
  • 對象的定義:
  • 開闢一個空間地址,堆內存
  • 把鍵值對存儲到堆內存下
  • 把空間地址賦值給對象名
console.log(fn);//fn()
console.log(f);//undefined
function fn(){}//函數聲明和定義
var f = function(){}//函數表達式-->箭頭函數
console.log(fn);//fn函數體
console.log(f);//undefined
console.log(fn());//打印兩次undefined 函數執行的時候打印f爲undefined,而且函數沒有返回值 打印一次undefined
function fn(){
console.log(f);
}
var f = function(){}//函數聲明
console.log(f2);//f2未定義 報錯
var 
var f = function f2(){}
console.log(f2)//f2未定義 報錯
setTimeout(funtion f2(){},1000)//函數做爲參數的時候不進行變量提高

函數聲明提高

一、函數的兩種建立方式
  • 函數聲明
  • 函數表達式

函數聲明的語法

f('nihao');
function f(name){
    console.log(name);
}
//能打印出nihao

函數表達式語法

f('nihao');
var f = function (name){
console.log(name);
}
//控制檯報錯 Uncaught ReferenceError:f id not function錯誤顯示f不是一個函數

兩種方式的區別:

  • 函數聲明又一個很是重要的特徵:函數聲明提高,函數聲明語句將會被外部腳本或者外部函數做用域的頂部(跟變量提高非長類似)。正是這個特徵,因此能夠把函數聲明放在調用它的語句後面。
var getName = function (){
console.log(2);
}
function getName(){
console.log(1);
}
getName();
//打印出2

這個例子涉及到了變量聲明提高函數聲明提高.正如前面說起到的函數聲明提高,函數聲明function getName(){}的聲明會被提早到頂部.而函數表達式var getName = function(){}則表現出變量聲明提高.所以,在這種狀況下,getName也是一個變量,這個變量的聲明將被提高到底部,而變量的賦值依然保留在原來的位置.須要注意的是:函數優先,雖然函數聲明和變量聲明都會被提高,可是函數會首先被提高,而後纔是變量。所以上面的函數能夠換成這個樣子

function getName(){
//函數聲明提高到頂部
console.log(1);
}
var getName;//變量聲明提高
getName = function(){
//變量賦值依然保留在原來的位置
console.log(2);
}
getName();//最終輸出2

在原來的例子中,函數聲明雖然是在函數表達式以後,可是因爲函數聲明提高到頂部,所以後面getName又被函數表達式的賦值操做給覆蓋了,因此控制檯輸出了2
Alt text
Alt text

console.log(f);//打印函數體
function f(){
    console.log(1);
}
f();//88
function f(){
    console.log(2);
}
function f(){
    console.log(3);
}
f();//88
f = 99;
function f(){
    console.log(88);
}
f();//f is not a function 
console.log(f);

ES6的let和const

var 與ES6中const 、let聲明的變量的區別
https://blog.csdn.net/qq_22855325/article/details/72843456

let不能和函數重名

  • const聲明的變量,
  • 若是是基本數據類型,那麼不能夠進行數據修改.
  • 若是 是引用數據類型值,就能夠操做引用地址,不能夠替換引用地址
  • 沒有變量提高
  • 不能夠重複聲明
  • 定義的變量不會給window增長屬性
  • 定義的是個常量,定義以後不能夠修改
  • 一旦聲明必須賦值
  • let雖然不會進行變量提高,可是會先檢查當前做用域下是否有重複命名
  • 沒有變量提高
  • 不能夠重複聲明
  • 定義的變量不會給window增長屬性
var a = 2;
if('a' in window){
    console.log(a);//造成暫時性死區,即在塊級做用域下,不能提早拿到let聲明的變量的值,打印2
    let a = 1;
}
let

ES6中提出了一個新的變量,不在於取代var,而在於解決ES5中var聲明中的一些痛點;這就是let
let的特色

  • 一、let是塊級變量,不存在於window下[非全局屬性],window,變量名是找不到的,它的做用範圍就那麼一小塊
  • 二、let不容許從新聲明同名變量,會拋出異常,具備惟一性
  • 三、let不容許沒聲明就使用,會拋出異常,只有執行該聲明的時候才能使用
  • 四、let有本身特點的閉包特性,好比在for循環的應用中
//1-
let tt = 'nihao';
console.log(tt);//打印出'nihao'
console.log(window.tt);//打印出undefined

//2-
function test2(){
    var abc = 99;
    let abc = 88;
    console.log(abc);
}
test2();//打印值:Uncaught SyntaxError:Indentifier 'abc' has already been declared

//3-
function test3(){
    console.log(test3);
    let test3 = '哈哈哈哈';
}
test3();//打印值:Uncaught ReferenceError:test3 is not defined

//4-每一次for村換都從新綁定一次做用域且脫離失效,就是let自身的特點
for(let i = 0;i<9;i++){
    //for循環造成保護機制
    console.log('循環內的值是:'+i);
}
console.log(i);//打印值
//循環內的值是:0
//循環內的值是:1
//循環內的值是:2
//循環內的值是:3
//循環內的值是:4
//循環內的值是:5
//循環內的值是:6
//循環內的值是:7
//循環內的值是:8
//Uncaught ReferenceError:i is not defined  塊級做用域 外界沒法訪問

查找上一級的做用域

一、在當前做用域下輸出變量值時,首先觀察是不是私有變量

  • 如何判斷一個變量是私有的
  • 當前變量有沒有被var過和function
  • 形參也是私有變量

二、若是變量不是私有的,就向上一級做用域查找

  • 上一級做用域判斷函數在哪定義的,函數上一級的做用域就是誰,跟函數執行沒有任何關係
  • 但獲取變量值時,首先是不是私有變量,若是不是就向上一級做用域查找,一級一級向上,直到window爲止,若是window也沒有,那麼就會報錯,這樣一級一級向上查找做用域就是做用域鏈

    堆內存的銷燬

    造成兩個虛擬內存:棧內存、堆內存
    棧內存:做用域
    引用數據類型
    在JS中的{}[]都是開闢一個新的空間地址
    谷歌瀏覽器:每隔一段時間,自動檢查佔用並是否銷燬
    火狐和IE:採用的計數的規則,當堆內存地址被佔用一次時,計數+1,不然-1,若是是被佔用0次,就回收

    私有做用域的銷燬

  • 函數的執行:造成一個私有的做用域,提供代碼運行環境,存儲基本數據類型

    閉包
  • 保護裏面的私有變量不受外界干擾
  • 存儲值
  • 保護機制:當前私有做用域中,有引用數據類型被外界所佔有,致使當前做用域變成一個不銷燬的做用域,裏面的變量就成了不銷燬的變量

通常狀況下,函數執行完成以後,當前做用域就會銷燬
函數沒執行一次就會開闢一個新的私有做用域,而且新的私有做用域和以前的做用域沒有任何關係,是兩個不一樣的棧內存

  • 不銷燬的做用域:
  • 函數執行return出一個引用的數據類型值
  • 函數執行return出的引用數據類型值而且被外界接收(被佔用)

    棧內存

    瀏覽器加載的時候,碰到引用數據類型,都會開闢一個新的內存空間,[對象:鍵值對;函數:代碼字符串],給這個內存空間賦一個16進制內存地址,將這個內存地址指向聲明的變量,這個內存空間就是堆內存
    堆內存的釋放,手動賦值null,[指向空指針];瀏覽器判斷該內存沒有變量就去收回它,就會釋放

function fn(){
    var t = 10;
    return function (){
        console.log(t++)
    }
}
var f = fn();
f();
f();
  • 不當即銷燬:
  • 須要等到裏面的小函數執行完成以後,那麼外層做用域就會銷燬
function fn(){
    var t = 10;
    return function (){
        console.log(t++);
    }
}
fn()();
var i = 0;
function fn(){
    //i = 5 6;
    return function(n){
        console.log(n + i++);
    }
}
var f = fn(5);
f(10);//15
f(20);//26
fn(8)(12);//20
fn()(18);//NaN
function fn (){
var a = 1 ;
return function (){
a++;
console.log(a);
}
}
var f = fn();
f(); //2
fn()(); //2
f(); //3
var obj= {
 i : 10,
fn:(function () {
var i = 0;
return function (n) {
console.log(n + i++)
}
})()
};
var f = obj.fn;
f(10);// 10
f(20);// 21
obj.fn(30);// 32 塊級做用域
obj.fn(40);// 43

this關鍵字

  • 函數中的this,指的就是函數的當前執行主體
  • 一、在全局做用域下,this 指向window
  • 二、函數體中的this,看函數執行前有沒有'.';若是有,那麼'.'前面是誰,this就指向誰;若是沒有'.',那麼會指向window
  • 三、若是給元素的事件行爲綁定方法,,那麼方法中的this,就會指向當前被綁定的那個元素
  • 四、回調函數中的this指向window
  • 五、自執行函數中的this通常都指向window
  • 六、forEachmap第二個參數能夠修改回調函數中的this
  • 七、構造函數中的this指向當前類的實例
  • 八、call、apply、bind能夠改變this關鍵字的指向
  • this是誰,和它在哪定義的以及在哪執行的沒有任何關係
    Alt text
    Alt text
    Alt text
function b() {
    console.log(this); //window
}
window.b();
var obj = {
    num:1,
    fn : function () {
        console.log(this);
        function m() {
            console.log(this);// window;
        }
        m()
    }
}
var f = obj.fn;
f(); // window
obj.fn();// obj
var obj = {
    num:1,
    f:{
        num:2,
        fn:function () {
        console.log(this);// obj.f
        }
    }
}
obj.f.fn()
//1.
setInterval(function () {
    console.log(this); // window
},1000)
//2.
(function () {
    console.log(this); //window
})()
//3.
var obj = {
    fn: (function () {
        console.log(this); //window
})()
}
var num =2;// 1 2
var obj = {
    num : 0,
    fn : function () {
        num = 1;
        // this-->obj
        (function (num) {
        // this --> window
            ++this.num;
            num++;
            console.log(num)// 1
        })(this.num)// 0
    }
}
obj.fn();
console.log(window.num,obj.num) //2 0

this的重點練習題

var num =2;// 1 2
var obj = {
     num : 0,
     fn : function () {
     num = 1;
     // this-->obj
    (function (num) {
    // this --> window
        ++this.num;
        num++;
        console.log(num)// 1
    })(this.num)// 0
  }
}
obj.fn();
console.log(window.num,obj.num) //2 0

Alt text
Alt text

設計模式-單例模式

模塊化開發

把一個項目按照頁面或者功能分割成不一樣的任務,交給項目中不一樣的成員開發.開發結束以後
將代碼合併到一塊兒.

  • 多人協做開發的問題: 變量名 函數名 衝突
  • 爲了防止全局變量污染: 閉包可是閉包並不完美,因此選擇搭配設計模式來進一步進行
    項目開發

    單例模式
  • 表現形式:就是一個對象:{name:xxx,age:function(){}};
  • 定義:把描述同一件事物的不一樣屬性放在同一個對象[空間]下,避免了全局變量的干擾;這種模式就是單例模式
  • 在設計模式當中,這個person不只僅是一個對象名,仍是一個命名空間,多個命名空間是相互獨立的,互不干擾
  • 好處:不受全局變量的污染和乾乾擾,而且能夠相互調用方法
  • 由來:單例模式的本質就是一個對象,它是object類上的一個實例,實例與實例之間互不干擾,叫作單獨的實例,簡稱"單例"

    高級單例模式
  • 定義:在高級單例模式當中,咱們不僅會把一個對象賦值給一個命名空間,咱們會先讓它執行一個自執行函數,[就造成了一個閉包,一個不銷燬的做用域],在自執行函數中,返回一個對象給這個命名空間
  • 好處:能夠在私有的做用域當中,建立不少的屬性和方法,僅須要把咱們使用的屬性和方法暴露在這個對象當中便可。相對於單例模式,能夠存儲不一樣方法中的公有變量

    工廠模式
  • 定義:把實現同一種功能的代碼放進一個函數中,當想實現相似功能時,只須要執行這個函數便可,傳參數不一樣就能夠.
  • 好處:減小了代碼的冗餘:"高內聚、低耦合"-->函數的封裝

    面向對象

  • OOP/OP面向對象的縮寫,面向對象思想
  • 定義:面向對象的封裝、繼承和多態,經過簡單的實例化,調用其餘的方法和屬性
  • JS就是經過面向對象的思想設計開發出來的
  • 須要瞭解 對象、類、實例
  • 對象:萬物皆對象,多爲一種泛指,能夠是任何物體
  • 類:對象中具備同一屬性和特徵的集合,類又分爲大類和小類
  • 實例:就是類中的一個具體的細分,咱們研究當前實例具備哪些屬性和方法,那麼證實當前類中的其餘實例也一樣具備

    JS中的內置類
  • JS中的任何數據類型都是它所屬的類,除了null、undefined
  • Number、String、Boolean、Object、Array RegExp、Function、Date...
  • 類的首字母都是大寫
  • 類的執行經過new來執行
  • Object對象類,被稱爲基類,在任何數據類型均可以經過__proto__[原型鏈]找到基類Object

    建立類
  • 字面量方式
  • 實例化方式
  • 引用數據類型方式建立 var ary = new Array('1')
    注意:

    • new Array(10):建立一個長度爲10的數組,數組中的每一項都是空
    • new Array('10'):若是隻傳遞一個實參,而且實參不是數字,至關於把當前值做爲數組的第一項存儲進來
    • new Array(10,20,30):若是傳遞多個實參,不是設置長度,而是把傳遞的內容當作數組中的每一項存儲起來
    構造函數
  • 定義:當一個函數經過new關鍵字來執行的時候,這個函數就不是普通函數了,它是一個構造函數,也是一個自定義類,當前的函數名就是類名,這個函數的返回值就是這個類的實例
  • 爲了讓構造函數和普通函數有一個區別,咱們建議寫構造函數的時候首字母大寫[類名]
  • 注意:通常狀況下,咱們寫業務邏輯的時候不會用到構造函數,可是在封裝庫、插件以及組件的時候就會用到構造函數模式
  • 構造函數執行的時候,若是沒有參數的時候,小括號能夠不寫
  • let person = new Person

    普通函數和構造函數的區別
  • 相同點:造成私有的做用域-->形參賦值-->變量提高-->從上到下執行-->做用域銷燬
  • 不一樣點:
    • 構造函數運行時,造成做用域後,在代碼運行以前,首先會給當前的做用域初始化一個空對象;而且讓當前做用域下的this指向這個空對象 當代碼運行結束,構造函數把函數體中的this做爲返回值返回
    • 構造函數若是並不須要傳參,能夠省略執行的小括號
    • 構造函數中的this,指向當前的實例
    • 在構造函數中,return 一個基本數據類型值,那麼對實例沒有任何影響;若是return出一個引用數據類型值,那麼會把默認returnthis替換掉.

      構造函數的執行過程
  • 造成一個私有的做用域
  • 形參賦值
  • 變量提高
  • 瀏覽器會建立一個對象,[開闢一個新的堆內存],將這個對象指向了this[堆內存指針指向this實例]
  • 代碼從上到下執行
  • 判斷當前構造函數是否有return,
  • 若是沒有return默認將實例返回;
  • 若是有return,
    • 若是return的是基本數據類型,對實例沒有影響
    • 若是是引用數據類型,那麼實例就是該引用數據類型
  • 構造函數中:建議不要輕易return引用數據類型
    Alt text

    私有屬性
  • 在構造函數中,給this添加屬性值和方法,都屬於當前實例的私有屬性

    公有屬性
  • 當前實例經過__proto__找到全部的屬性和方法都輸屬於當前實例的公有屬性
  • 實例想要調取公有屬性,直接能夠調取,底層及時經過__proto__去找這個屬性
  • 用in這種方式來判斷,當前屬性名[公有屬性+私有屬性]是都屬於這個對象
    console.log('hasOwnProperty' in person1);
  • Object類提供一個hasOwnProperty,這個方法判斷當前屬性是不是該實例的私有屬性:返回布爾值console.log(person1.hasOwnProperty("age")) //true console.log(person1.hasOwnProperty("valueof")) //false
    例題:本身封裝一個方法,判斷當前屬性是不是當前實例的一個公有屬性hasPubProperty
function hasPubProperty(obj,item){
        //先檢測是不是屬性
        return item in obj &&!obj.hasOwnProperty(item);
    }
    console.log(hasPubProperty([], 'toString'));
JS中的函數
  • 普通函數、類(自定義類和內置類)、函數類的實例

    對象
  • 普通對象(對象數據類型)
  • 構造函數new出來的一個實例,也是一個對象
  • 類上面的原型也是一個對象
  • 函數也是一個對象

    學習原型模式須要記住三句話
  • 全部的函數都天生自帶一個屬性,叫作prototype(原型),它是一個對象,既然是對象,那就是一個堆內存
  • 全部函數的原型上面(都是開闢的這個堆內存),都天生自帶一個屬性,叫作constructor(構造函數),它指向當前類自己
  • 全部的對象都天生自帶一個屬性__proto__,它指向當前類的原型

  • 全部的函數數據類型(普通函數、類(內置的、自定義))都是Function的一個實例;Function是全部函數的基類;
  • 5.全部的對象數據類型(實例、prototype、對象)都是Object的一個實例;Object是全部對象數據類型的基類;
  • Function 首先是本身的一個實例;
    Alt text
function People(name){
    let age = 9;
    this.name = name;
    this.age = age;
}
People.prototype.say = function () {
    console.log(this);
};
let person1 = new People('zf');
let person2 = new People('zhufeng');
//person1屬於People類
//__proto__指向類People的原型prototype
console.log(person1.__proto__ == People.prototype);//true

Alt text

原型鏈
  • 定義:一個實例要找屬性,優先會去找本身的私有屬性,若是本身的私有屬性沒有,那就經過__proto__找到本身所屬類的原型上面的公有屬性,若是公有屬性尚未,繼續經過__proto__找到本身的所屬類的原型直到Object[基類]的原型上,一直找到基類尚未的話,直接返回undefined

    Object類和Function類
    Function類:
  • 全部的類都是經過函數的方式來建立,由此能夠得知,全部的類(包括基類Object)都是函數類的一個實例
  • 判斷一個實例是否屬於一個類:intanceof
    console.log(Number instanceof Function); //true
    console.log(String instanceof Function); //true
    console.log(Object instanceof Function); //true
  • constructor:經過實例來調用這個方法,指向當前類自己
  • 萬物皆對象,JS中的任何數據類型均可以經過proto
    Alt text

相關文章
相關標籤/搜索