JavaScript数据类型分两种:
基本数据类型:null undefined Boolean Number String
按值访问,可以操作保存在变量中的实际的值。
引用数据类型:Object
引用类型的值是保存在内存中的对象,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。实际上是在操作对象的引用而不是实际的对象。
引用类型的值是按引用访问的。这种说法不严谨,当复制保存着对象的某个变量时,操作的是对象的引用。在为对象添加属性时,操作的是实际的对象。
在全局执行上下文中,this总是指向全局对象,例如浏览器环境下this指向window对象。
在函数执行上下文中,this的值取决于函数的调用方式,如果被一个对象调用,那么this指向这个对象。否则this一般指向全局对象window或者undefined(严格模式)。
只有函数声明格式的函数才会存在函数声明提前,比如函数表达式、构造函数都不存在函数声明提前
函数声明方式,存在声明提前,在创建阶段它就是一个明确的函数了,
function func() {}
函数表达式创建的函数,不存在声明提前
var func = function(){}
使用var声明,在创建阶段会给一个undefined作为初始值
-
let和const,它们在创建时,是没有初始值的,状态为uninitialized(未初始化),在声明它之前使用它,是不合法的,对应了ES6中暂时性死域的概念
-
暂时性死区的本质是,只要进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
// 第一种情况 if(true){
// console.log(tmp);
let tmp;
} // ReferenceError: Cannot access 'tmp' before initialization // 第二种情况,暂时性死区 if(true){
tmp = 2;
let tmp;
} // Uncaught ReferenceError: Cannot access 'tmp' before initializationif(true){
let tmp;
console.log(tmp); }// undefined
let const在同一作用域不能重复声明
function fn(){
var a = 1;
let a = 2;
}
fn();
// SyntaxError: Identifier 'a' has already been declared
重点:同一作用域下,函数会首先被提升,然后是变量声明提前。声明提前,赋值原地不变
函数声明提前,变量声明也提前,到底谁会更提的更前?假设两者都用的同一命名声明,到底最后会输出啥
console.log(a); // ?
a(); //?
var a =3;
function a(){
console.log(10);
}
console.log(a); //?
a = 6;
a(); //?
输出结果:
ƒ a(){ console.log(10); }
10
3
Uncaught TypeError: a is not a function
函数声明和类声明之间的一个重要区别在于, 函数声明会提升,类声明不会。
let p = new Rectangle(); // ReferenceError
class Rectangle {}