JS第一周學習筆記整理

来源:https://www.cnblogs.com/kjz-jenny/archive/2018/07/15/9315241.html
-Advertisement-
Play Games

總結了一周學習Js的筆記、關於git、GitHub、this、作用域等 ...


目錄

JS正式課第一周筆記整理

  • webstorm : 代碼編輯器
  • 瀏覽器: 代碼解析器;
  • Git : 是一個工具;用於團隊協作開發項目管理代碼的工具;在工作中用git、svn
  • svn : 集中式;
  • 集中式:需要一個中央伺服器;每次開發前需要從中央伺服器把最新的代碼拉取下來,然後進行開發;並且需要網路;
  • git : 分散式;
  • 分散式:每個人的電腦都是一個中央伺服器;不需要網路也可以進行提交代碼;

DOS命令

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

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

    Git

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

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

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

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

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

    推送複原過程

    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

變數提升

https://blog.csdn.net/zjy_android_blog/article/details/80863425

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)//函數作為參數的時候不進行變數提升

函數聲明提升

1、函數的兩種創建方式
  • 函數聲明
  • 函數表達式

函數聲明的語法

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的特點

  • 1、let是塊級變數,不存在於window下[非全局屬性],window,變數名是找不到的,它的作用範圍就那麼一小塊
  • 2、let不允許重新聲明同名變數,會拋出異常,具有唯一性
  • 3、let不允許沒聲明就使用,會拋出異常,只有執行該聲明的時候才能使用
  • 4、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  塊級作用域 外界無法訪問

查找上一級的作用域

1、在當前作用域下輸出變數值時,首先觀察是否是私有變數

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

2、如果變數不是私有的,就向上一級作用域查找

  • 上一級作用域判斷函數在哪定義的,函數上一級的作用域就是誰,跟函數執行沒有任何關係
  • 但獲取變數值時,首先是否是私有變數,如果不是就向上一級作用域查找,一級一級向上,直到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,指的就是函數的當前執行主體
  • 1、在全局作用域下,this 指向window
  • 2、函數體中的this,看函數執行前有沒有'.';如果有,那麼'.'前面是誰,this就指向誰;如果沒有'.',那麼會指向window
  • 3、如果給元素的事件行為綁定方法,,那麼方法中的this,就會指向當前被綁定的那個元素
  • 4、回調函數中的this指向window
  • 5、自執行函數中的this一般都指向window
  • 6、forEachmap第二個參數可以修改回調函數中的this
  • 7、構造函數中的this指向當前類的實例
  • 8、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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 語言:C 開發工具:Visual Studio 2017 問題場景介紹: nuget引用的MySql.Data版本是6.10.5,MySQL的資料庫連接串如下: 可以正常訪問MySQL資料庫 更新nuget,MySql.Data版本是8.0.11,報錯 解決方案:連接字元串添加 修改後的資料庫連接串 ...
  • 置SQLServer,允許遠程連接 按照上面的文章一步步配置後,遠程連接出現下麵所示的報錯(Navicat 和 SQL Server Management Studio) SQL Server Management Studio的報錯信息為: 在與 SQL Server 建立連接時出現與網路相關的或 ...
  • 首先看下麵一條比較完成語句,都是比較常見的關鍵字。 我們來詳細分析一下sql語句的邏輯處理順序,雖然select在每條語句的第一位,但實際上它是被最後才處理的 1.from 2.where 3.group by 4.having 5.select 6.order by 在仔細分析每個執行順序代表的意 ...
  • MySQL基本簡單操作 學會了安裝 ,那麼就將它利用起來。(/滑稽臉) 之前想學習 (Windows下配置真麻煩),學會了 就方便了,直接使用 創建一個 服務豈不美滋滋。創建容器的步驟可以看一下 "分享04" 的 的創建過程。 首先檢查一下本地鏡像。 [root@promote ~] docker ...
  • git
    "Github 訪問時出現Permission denied (public key) bairui的個人頁面 開源中國" "git遠程分支和refs文件詳解 CXH.ME" "git版本控制基本命令_琴瑟起_新浪博客" "【git】.gitignore用法 簡書" "碼雲(Gitee.com)幫助 ...
  • 前言 在本系列上一篇文章Android包管理機制(一)PackageInstaller的初始化中我們學習了PackageInstaller是如何初始化的,這一篇文章我們接著學習PackageInstaller是如何安裝APK的。本系列文章的源碼基於Android8.0。 1.PackageInsta ...
  • 網路請求數據格式: 總的網路請求數據格式: 外層數據格式 數據模型: .h文件 .m文件 initWithDictionary: 解析數據 解析數據: 結果: 中間層數據格式 1 categories = ( 2 { 3 alias = Politics; 4 name = "\U65f6\U653 ...
  • 前言 包管理機制是Android中的重要機制,是應用開發和系統開發需要掌握的知識點之一。 包指的是Apk、jar和so文件等等,它們被載入到Android記憶體中,由一個包轉變成可執行的代碼,這就需要一個機制來進行包的載入、解析、管理等操作,這就是包管理機制。包管理機制由許多類一起組成,其中核心為Pa ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...