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
经过以上的分析能够得出原型链图,以下图所示: