js创建变量的基础知识

204 阅读4分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

es5变量声明方式var存在两个问题:

  • 变量提升,即变量不需要先声明后使用,也可先使用后声明。
  • 变量的作用域只有两种:全局作用域和局部作用域。

let声明的变量作用域为块级作用域,且必须先声明后使用,使代码更加严谨。

看下面这题,输出结果应为多少?

 var a = 10;
 (function(){
 console.log(a);
 var a = 100;
})();

答案是undefined,因为var声明变量的提升效果,这里相当于:

 (function(){
  var a;
  console.log(a);
  a = 100;
 })();

值得注意的是,JavaScript永远是先解析声明函数,再解析变量。

函数执行

目的:把之前创建函数在内存空间中存储的“代码字符串”变为真正的JS代码执行,从而实现相关的效果

  • 第一步:首先形成一个私有的作用域(给接下来的代码执行提供一个私有的环境)
  • 第二步:到私有作用域中依然要先进性词法解析
    • 先给形参赋值
    • 私有作用域中的变量提升
  • 第三步:在私有作用域中把代码自上而下执行

堆栈内存

JS中有两大内存:堆内存(Heap)、栈内存(Stack) 堆内存作用:用来存储内容的(对象存储的是键值对,函数存储的是代码字符串) 栈内存作用:也可以被称为作用域,是代码解析和执行的环境

Symbol数据类型

ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。

对变量或值调用 typeof 运算符将返回下列值之一:

  • undefined - 如果变量是 Undefined 类型的
  • boolean - 如果变量是 Boolean 类型的
  • number - 如果变量是 Number 类型的
  • string - 如果变量是 String 类型的
  • object - 如果变量是一个对象或 Null或者数组 
  • function -如果变量是个函数名
  • symbol  -es6引入的数据类型

注意不要和JavaScript基本数据类型搞混,

基本数据类型有7个:undefined、null、Boolean、String、Number、Object、Symbol     (根据阮一峰老师的教程,基本数据类型就这7种,不包括Array)

  • 每次创建Symbol,它的值都不一样
  • Symbol里面可以传入一个参数,用于描述你创建的Symbol,传入参数对他的值没有影响
  • 应用:在不同的块中,临时重写变量
  • Symbol 值不能与其他类型的值进行运算,会报错。
  • Symbol 值作为对象属性名时,不能用点运算符

new做了什么

  • 无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
  • 在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针(就是指向新创建的函数)。
  • 通过这个构造函数(原型对象的构造函数),可以继续为原型对象添加其他属性和方法。
  • 当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262第5版管这个指针叫 [[Prototype]]。脚本中没有标准的方式访问[[Prototype]],但FirefoxSafariChrome在每个对象上都支持一个属性__proto__;而在其他实现中,这个属性对脚本是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例和构造函数的原型对象之间,而不是存在于实例和构造函数之间