变量的声明和原理

变量的声明

本节知识点

在javascript里 声明变量简写为 var ;通过var name 就可以声明一个变量了;
注意变量的声明和定义是两回事;

var name;            //变量的声明
name="朱邦邦";        //变量的定义
var name="朱邦邦";    //变量的声明加定义

var name=”朱邦邦”;其实是实现两步;
第一步 var name;先声明一个name的变量;
第二步 name=”朱邦邦” 创建数据"朱邦邦"这个字符串,并且把字符串"朱邦邦"这条数据赋值给name这个变量;在定义(赋值)变量的name值;

这个时候name的类型就是所代表值的类型;可以通过typeof来检测;通过检测可以知道这个变量所代表的值是一个字符串类型的数据;

var name="朱邦邦",
    gender;
console.log(name,typeof name);      //朱邦邦 string
console.log(gender,typeof gender);  //undefined "undefined"

虽然关键字var不是必须的,但是最好每次声明一个新变量都加上;

需要注意的是变量本身是没有意义的,只是数据的媒介(代号),我们说的变量默认是这个变量名所代表的数据,并不是这个变量名本身;这点需要注意的;

类似我们的名字,"特斯拉"这三个字没有特殊意义,当这三个字与汽车品牌,或者一位科学家关联在一起的时候,这三个字才是有有意义的;

变量

↑ 返回目录

一、变量的命名:

变量的名字可以千变万化,但是也有其中的规则需要遵守;(必须遵守的);

  • 1、变量名是由数字、字母、下划线组成的,其中字母里大小写字母均可;

  • 2、变量名首位不是能数字,可以是字母下划线;首位后的位置可以是数字,字母,下划线;

  • 3、不能使用关键字和保留字作为变量的名字(需要避开的名字);

    • 关于关键字和保留字,这个可以拿生活中的现象举例子,大人给小孩起名字的时候,小孩的名字一定不能和他父亲母亲的名字一样;当然也不能和爷爷,奶奶,外公,外婆,舅舅,姑姑等等这些名字一样;这个就是现实中约定俗成的规则;
    • 在JS中,也有些单词是有特殊意义的,或者是为了以后语言升级做准备的;而这些单词就不能作为变量名;比如前面接触的typeof,function;这样的单词就不能作为变量名;
  • 4、变量区分大小写,test和Test是不一样的,必须严格一样,才算是一个变量的;(在javascript里,onclick 必须要写出onclick,不能写成onClick;)

变量命名的优化方法(推荐遵守的,非强制);

使用变量作为值的符号名,变量的名字又叫标识符;

优雅的变量命名方法是可以一眼扫过就知道什么意思的;不会浪费时间在思考变量名所代表的意义;

如果给"门"命名为name1,给"桌子"命名为name2,给"冰箱"命名为name3;那么日常生活就乱套了,听起来这种在现实生活中会很奇怪和搞笑;

但是很多前端新手经常犯变量命名的类似毛病;

变量命名的意义是直观易理解,读到第一行代码时候就知道什么意思,假如隔了几十上百行代码后仍然可以明确他的意义;

下面是收集的一些变量命名方法;

  • “-”连接符方法;
    • 比如给我桌子上门钥匙命名;my-room-door-key 和 my_room_door_key;
    • 这种方法用”-”和下划线"_"连接符来链接单词,区别是下划线在选择变量的时候,鼠标双击可以全部选择;
  • 驼峰命名法;这种命名方法有两种方式
    • 大驼峰:每个单词的首字母大写;MyRoomDoorKey
    • 小驼峰:第一个字母小写,其它字母大写;myRoomDoorKey
  • 匈牙利命名法;变量由类型+对象描述组成;
    • 对象(Object)用o表示;
    • 函数(function)用fn表示;
    • 数组(array)用a表示;

上面的但中方法是目前最流行的规范;但是各有利弊;下面是我个人自己的书写习惯;

我个人的写法;

  • Class名:用”-”连接符的方法;class=”header-nav” 比如这样的;
  • JS变量名:myRoomDoorKey;小驼峰
  • data-diy_attr 自定义属性;
  • j-trigger-target JS中需要用的类名
  • jQuery对象名: m y K e y myKey;小驼峰前面加 ;这种方法是从匈牙利+驼驼峰总结出来的;其实真实项目中,很少有匈牙利命名法的;匈牙利命名法见过最多的都是出现在写DEMO的时候用;
  • 除非特别难起的变量名,否则不要用中文拼音做变量名,但是遇到难起的变量名,使用中文也别有负担,但是禁止中英文混搭;
  • 注释可以辅助整理思路;

不要听信某些教材和视频中说的严禁用拼音命名的话,有的甚至还把linux创始人林纳斯的代码风范拿出来说事。其实那些并没有什么软用;开始就和大家说了变量是用来区别不同数据的;而优化变量名的意义在于能够快速识别这个变量名所代表的数据;

比如你要记录游戏场景下的角色出血值;你还要想半天单词,或者找翻译,然后起出来的变量名,自己下次看到或者别人看到的时候还要去翻译或者思考下;这种情况下,为什么不直接用 chuxue这种的方式呢?只需要后面加一行注视说明什么意思就可以了;

很反感为了遵守优化规则而脱裤子放屁的方式的;曾经在项目中遇到过一个真实的事;某个变量看了半天不知道到底代表什么意思(因为当时有接触到差不多10种的用户相关类型的金额数),查了翻译也没有查到;后来问了下,才知道那个坑货把单词给拼错了两个字母;

<div class="page-var-demo" id="page-var-demo">
    <!--class="page-var-demo"用来设置样式;id="page-var-demo"用给JS用;-->
    <div class="btns-groulp">
        <a href="javascript:;" class="xxxx xxxxx j-open-demo" data-demo_id="456465465">打开演示窗口</a>
        <!--j-open-demo 这些是给JS用来触发某些事件用的,data-demo_id用来储存需要的值的-->
        <a href="javascript:;" class="xxxx xxxxx j-set-demo">设置演示数据</a>
    </div>
</div>

↑ 返回目录

知识点二、变量的声明:

变量通过var来声明;

下面是要避免的,否则写代码的时候可能会把自己给坑了;

  • 重复声明;
  • 不声明直接赋值
  • 不要更改变量的类型,开始是值类型,后面就不要改为数值或别的别的了,开始如果用来储存某个属性值,就不要再用在别的属性上了;

推荐:先声明,后定义;

  • 需要读写的变量,读写前,一定要声明;
  • 需要运算的变量,运算前,一定要赋值;
  • 书写的时候,推荐把变量名放在页面的上面(上部分)去声明+定义;这样不仅可以放心大胆的用,而且可以方便查找变量;
  • 在任何情况下声明变量都要用var先声明;在使用一个变量之前应当先声明,变量是使用关键字var来声明的;
  var a=1;
  function test(){
    var b=c=2;//这时候会隐式声明全局变量;
  }
  test();
  console.log(a,c)

上面是非常不好的写法;不要写 var b=c=2 这种声明;上面代码中c就会被隐式声明为全局变量;

下面这种写法是可以的

var a= 1,c;
function test(){
  var b=c=2;
}
test();
console.log(a,c)

因为开始c已经声明了,后面只是给c赋值;

多个变量声明赋值时候,同一类的变量推荐下面这种写法;

  var name="zhuanbang",
      age=26,
      height="174cm";

这样既可以简洁,又保证可读性;

注意:任何变量赋值前都需要声明变量,不要隐式创建全局变量;

重复声明和遗漏声明的区别:

在javascript里使用 var 重复声明是合法而且不会有任何事情的,如果重复声明带有初始化的值,那么就和一条简单的赋值语句没有什么两样,但是如果你忘记声明了,试图读取一个没有声明的变量的值,javascript可能会报错;

在严格模式中,给一个没有声明的变量赋值也是会报错的;非严格模式下虽然不会报错,但是不要抱着侥幸的心理;这是一个不好的习惯,建议始终使用var来声明变量;

ES6扩展了2种声明方法;

  • let
    • 声明一个块作用域的局部变量,可以选择将其初始化为一个值
  • const
    • 声明一个只读的常量

使用关键词 var。例如 var x = 42。这个语法可以用来声明局部变量和全局变量。

使用关键词 let。例如 let y = 13。这个语法可以用来声明块作用域的局部变量;ES6中更推荐用这个来声明变量;

用 var 或 let 声明的且未赋初值的变量,值会被设定为 undefined;undefined 值在布尔类型环境中会被当作 false。所以程序中,利用数据的true和false判断逻辑也是常见的;

常量不可以通过赋值改变其值,也不可以在脚本运行时重新声明。它必须被初始化为某个值。

const myName="zhu";
let age=2;
age =22;
// myName=4;//Error
console.log(age);

常量的作用域规则与 let 块级作用域变量相同。若省略const关键字,则该标识符将被视为变量。

if(true){
    var a=2;
}
if(true){
    let b=3;
}
console.log(a);
console.log(b);//b is not defined

在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量。

↑ 返回目录

知识点三、变量类型:

变量分为值类型和引用类型:typeof可以简单的检测数据类型;

值类型的特点:

  • 占用空间固定,保存在栈中;
  • 保存与复制都是值本身;
  • 使用typeof检测数据的类型;
  • 基本数据类型是值类型;

引用类型的特点;

  • 占用空间不固定,保存在堆中;
  • 保存与复制的是指向对象的一个指针;
  • 使用instanceof检测数据的类型;
  • 使用new()方法构造出的对象是引用型;
基本数据类型和引用数据类型详解;

ECMAScript规定变量包含两种不同数据类型的值,基本类型值和引用类型值;在给变量赋值的时候,解析器必须要明确这个值是基本类型还是引用类型值,因为他们的赋值方式是不同的;string/number/boolean/null/undefined都是基本数据类型;因此可以操作保存在变量中是实际值,此时变量储存的是实际的值;而引用类型的值是保存在内存中的,此时变量储存的是内存的地址,而不是真实的值;而我们操作引用类型的变量时,实际操作的是它引用地址对应的对象,而不是直接操作对象的;
基本类型和引用类型的操作原理

var number1= 1,
    number2=number1;
number1=2;//改变了number1的值
console.log(number1);//2
console.log(number2);//1
console.log(number1===number2);//false

var obj1={name:"zhu"},
obj2=obj1;
obj1.name="zhuanbang";
console.log(obj1.name,obj2.name);//zhuanbang,zhuanbang
console.log(obj1.name===obj2.name);//true

原理图如上;

基本数据类型,也叫原始数据类型,不可能数据类型;引用数据类型,也叫对象类型和可变类型;

不可变的意思是,这个值是不可以改变的,如果变量修改了字符串,以前的字符串会销毁,然后再次赋值;而可变的意思是可以改变对象的属性值;这只是对数据来说的,javascript本身是可以自由进行数据类型转换的,javascript的变量是无任何类型的,只是一个标识符,变量可以赋值任何类型的值;string的所有方法,都是不会改变原有字符串的,比如toUpperCase返回的值,其实是一个新字符串,原有字符串不变,这就是string方法的原理;

↑ 返回目录

知识点四、全局变量和局部变量:

全局变量;有两种方式可以产生全局变量;

  • 在函数体外定义的变量;
  • 在函数体内部定义的无var的变量;
  • 上面两个说法都不算准确,但是可以先这么记着,后面学习作用域的时候,会仔细分析;

全局变量的用法:在任何位置都可以调用

  • 直接调用变量名;(不含有同名局部变量和参数时);
  • 通过window.varName 来调用;

局部变量;局部变量有两种类型;

  • 在函数内部使用var声明的变量;
  • 函数的参数变量

局部变量的调用方法:

  • 当前函数体内部;

扩展:在函数体外部不能调用函数体内部的数据,属于闭包的机制,后面会有介绍;

变量名的优先级(当有多个名字重复的变量时候)

  • 局部变量高于同名全局变量;
  • 参数变量高于同名全局变量;
  • 局部变量高于同名参数变量;

全部变量和局部变量的特性

  • 忽略块级作用域
  • 全部变量是全局对象的属性
  • 局部变量是调用对象的属性;
  • 作用域链;
    • 内层函数可访问外层函数局部变量;
    • 外层函数不能访问内层函数局部变量;
  • 生命周期:
    • 全局变量;除非被显示删除,否则一直存在;
    • 局部变量:自声明起至函数运行完毕或被显示删除;
    • 回收机制:
      • 标记清除
      • 引用计数;

↑ 返回目录

知识点五、注释和语法建议;

注释

javascript的注释。单行注释是"//注释文字",多行注释是/注释文字/

//注释文字

/*
* 多行注释1
* 多行注释2
* /
语法建议:
//bad
var a=2 //没有分号,也是可以的,但是不推荐这么做;压缩的时候可能会出错; 理论上加分号性能会更好,浏览器不必花时间判断是否要加分号了(无论加不加分号,浏览器解析的时候会判断的,如果需要加的地方没有加,浏览器解析时候会加上去之后再解析)

//good
var b=3;
不建议使用var a=b=c=1;这种的写法;

if-else 推荐加上{};

//bad   
if(true)
    console.log("bad");//有效,但是容易出错,不要使用;

//good
if(true){
    console.log("good");//推荐使用,可以降低修改代码时出错的几率,可以让代码的意图更明确;
}

分号很多地方是可选的,推荐除了{}外都给加上;语句也可以换行的,但是有两个例外不能换行

  • 1、return、break、continue
  • 2、++,–运算符的时候;

↑ 返回目录

六、练习题:

01-02-01、var a=b=c=d=1是什么意思?如果接下来在写一句a=9;a,b,c的值分别是多少?
01-02-02、var a=b=c=d=[1,2,3,4,5]是什么意思?如果接下来再写一句d[5]=0,a,b,c的值分别是多少?
01-02-03、var a=b=c=d=[1,2,3,4,5]是什么意思?如果接下来在写一句d=[0],a,b,c的值会发生变化吗?
01-02-04、var n=(1,2,3,4,5),n的值是多少?
01-02-05、什么叫全局变量,什么叫局部变量?是如何定义出来的;
01-02-06、什么叫保留字?在定义变量时我们应该注意哪些?
01-02-07、定义变量名或者方法、属性名,有什么规范原则吗?请说一说
01-02-08、说一说html代码,css代码和js代码的注释写法;
01-02-09、以下哪些单词不属于javascript保留字

  A、with
  B、parent
  C、class
  D、void

参考 - EC前端 http://www.ecmaer.com

猜你喜欢

转载自blog.csdn.net/chenmozhongzong/article/details/89672556