let&const&原型鏈的理解

1、let函數

let 是用來聲明變量,相似var,可是其聲明的變量,只在聲明的代碼塊內有效。而且不容許在相同做用域內,重複聲明同一個變量;也不能在函數內部從新聲明參數。ui

for(let i =0;i<3;i++){
     let tempObj = {
         name:'tom'
     }
     //let tempObj = {} //SyntaxError: Identifier 'tempObj' has already been declared
     var tempArr = [23]
 }
console.log(tempObj)  //tempObj is not defined
console.log(tempArr)  //[23]

let命令所聲明的變量必定要在聲明後使用,不然報錯。
var命令會發生「變量提高」現象,即變量能夠在聲明以前使用,值爲undefined。this

console.log(a); // 輸出undefined
 var a= 2;
​
 console.log(b); // 報錯ReferenceError
 let b= 2;

在塊級做用域內部的聲明函數,建議不要使用函數聲明語句;優先使用函數表達式。spa

由於函數聲明相似於var命令,會發生變量提高。即把函數聲明提高到其所在的塊級做用域的頭部。
// 建議不要使用
 {
     let a = 'secret';
     function f() {
         return a;
     }
     //至關於
     //var f= function () {  //f會變量提高
     //    return a;
     //}
 }
 // 優先使用函數表達式
 {
     let a = 'secret';
     let f = function () {
         return a;
     };
 }


塊級做用域必須有大括號,若是沒有大括號,JavaScript 引擎就認爲不存在塊級做用域。函數聲明也是如此。prototype

if (true) let x = 1; //會報錯
 if (true) {  //正常
     let x = 1;
 }

2、const指針

聲明一個只讀的常量。一旦聲明,常量的值就不能改變。必須當即初始化,不能留到之後賦值。
其做用域與let命令相同:只在聲明所在的塊級做用域內有效。
const只能保證這個指針是固定的,也就是說對象中的屬性是可變的。
可使用Object.freeze方法。能夠將聲明的對象凍結code

var constantize = (obj) => {
     Object.freeze(obj);
     Object.keys(obj).forEach( (key, i) => {
         if ( typeof obj[key] === 'object' ) {
             constantize( obj[key] );
         }
     });
 };

聲明變量的六種方法對象

var 
function 
let 
const 
import
class

var命令和function命令聲明的全局變量,是頂層對象的屬性;而let、const、class命令聲明的全局變量,並不屬於頂層對象的屬性。blog

var a = 1;
window.a // 1
let b = 1;
window.b // undefined

js中獲取頂層對象的兩種方法。圖片

function foos() {
     (typeof window !== 'undefined'
         ? window
         : (typeof process === 'object' &&
             typeof require === 'function' &&
             typeof global === 'object')
             ? global
             : this);
 }
​
​
 // 方法二
 var getGlobal = function () {
     if (typeof self !== 'undefined') { return self; }
     if (typeof window !== 'undefined') { return window; }
     if (typeof global !== 'undefined') { return global; }
     throw new Error('unable to locate global object');
 };

在ES2020 語言標準中,引入globalThis做爲頂層對象。任何環境下,globalThis都是存在的,均可以從它拿到頂層對象,指向全局環境下的this。

//兩次打印的對象是相同的
console.log(globalThis)
class Infos {
    gets() {
        console.log(globalThis)
    }
}
let ss = new Infos();
ss.gets();

3、js原型鏈
一、對象有__proto__屬性,函數有prototype屬性;對象由函數生成。
二、生成對象時,對象的__proto__屬性指向函數的prototype屬性。
三、函數也是對象的一種,因此函數有__proto__屬性

//首先咱們先建立一個構造函數Foo
let  Foo = function() {}
//實例化
let f1= new Foo();
console.log(f1.__proto__ === Foo.prototype)  //true
​
​
//而Foo函數對象都是由Function函數生成的:
console.log(Foo.__proto__ === Function.prototype) //true
console.log(Foo.prototype.constructor === Foo) //true
​
​
//Function函數自己做爲對象時,生成它的函數是他自身!
console.log(Function.__proto__ === Function.prototype) //true
console.log(Function.prototype.constructor === Function) //true
​
​
//函數默認的prototype是系統自動生成的一個對象:
console.log(Foo.prototype.__proto__ === Object.prototype) //true
console.log(Function.prototype.__proto__ === Object.prototype) //true
​
​
//新建對象
let o1= new Object(); //或者 let objs = {}
console.log(o1.__proto__ === Object.prototype) //true
​
​
//Object函數既然是函數,那生成它的函數天然是Function函數
console.log(Object.__proto__ === Function.prototype) //true
console.log(Object.prototype.constructor === Object) //true

經過以上的分析能夠得出原型鏈圖,以下圖所示:
在這裏插入圖片描述

相關文章
相關標籤/搜索