JavaScript从入门到出门

( 文 中 一 些 小 的 注 释 可 能 会 令 大 家 觉 得 没 有 必 要 , 但 是 对 于 一 些 童 鞋 可 能 确 实 有 用 < 比 如 我 这 样 的 小 菜 鸡 > 小 声 b b ) (文中一些小的注释可能会令大家觉得没有必要,但是对于一些童鞋可能确实有用<比如我这样的小菜鸡>小声bb) <>bb

变量声明,作用域

众所周知,JavaScript变量声明共有三种关键字 var let const

对于var,在 ECMAScript 的所有版本中均可使用,而let与const只能在ECMAScript6(ES6)及之后的版本中使用。然而ES6新增的let与const直接受到了大多数程序猿的追捧即大多数童鞋不再使用var而只使用const,下面就让小王和大家好好掰扯一下这些关键字(说的不好或者不对的地方望大家能够指正)
要搞明白这三种关键字首先我们需要了解作用域

作用域(Scope)

作用域就是变量与函数的可访问范围,作用域决定了代码区块中变量与其他资源的可访问性(可见性),在ES6之前,只存在全局作用域和局部作用域。ES6之后,出现了块级作用域。

全局作用域

全局作用域顾名思义就是作用域是全体即所有脚本与函数均能访问到,函数之外声明的变量就是全局变量

    var name = "WDY";
    function my(){
   
        //里面可以调用name
    }

局部作用域

局部作用域顾名思义就是作用域是局部即不是所有均能访问,函数之内的声明就是局部作用域

    function my(){
   
        var name = "WDY";
    }
    //不可访问name

块级作用域(ES6新增)

由最近一对包含花括号界定{} 即if块,while块,function块,甚至是单独的块

    if(true){
   
        let name = "WDY";
    }
    //外部不可访问
    while(true){
   
        let name = "WDY";
    }
    //外部不可访问

var

1. 声明范围(函数作用域)
    function sayHi(){
   
        var m = "Hi";
    }
    sayHi();
    console.log(m)  //报错,不可访问
    //这也表示局部变量在函数退出时就被销毁了
2.变量提升(绝活儿)
使用var关键字声明的变量会自动提升到函数作用域顶部
    function sayName(){
   
        console.log(name);
        var name = "WDY";
    }
    sayName();  //undefined
    //!!注意变量提升意味着不会报错而是输出undefined,虽然提升了,但是不会读到值,所以不会输出WDY
    //即可以后定义变量,在函数中它相当于在顶部命名即
    function sayName(){
   
        var name = "WDY";
        console.log(name);
    }
  
    function sayName(){
   
        console.log(name);
        let name = "WDY";  //报错
    }

let

1.声明范围(块级作用域)
    if(true){
   
        var name = "WDY";
        console.log(name);  //WDY
    }
    console.log(name);  //WDY
    
    if(true){
   
        let name = "WDY";
        console.log(name);  //WDY
    }
    console.log(name);  //报错:name没有定义
let不允许同一块级作用域中重复声明
    var name;
    var name;  //可行
    
    let name;
    let name;  //报错
不在同一块级作用域中可以重复声明
    let name = "WDY";
    console.log(name);  //WDY
    if(true){
   
        let name = "王大宇";
        console.log(name);  //王大宇
    }
2.全局声明
在let全局作用域中声明的变量不会成为window对象的属性(var会吗?会!)
    var name = "WDY";
    console.log(window.name);  //WDY
    
    let name = "WDY";
    console,log(window.name);  //undefined

const

1.声明范围(块级作用域)
2.不允许重复声明
3.声明变量时必须初始化变量,且变量一经声明不可修改,声明对象后对象不可修改但其键可以
    const name;  //×

    const name = "WDY";
    name = "傻子";  //×
    
    const P1 = {
   };
    p1 = {
   }  //×
    
    const p1 = {
   };
    p1.name = "WDY";
    console.log(p1.name);
    //如果想让整个对象都不能修改可以使用Object.freeze(),不会报错,但不会成功
    const p1 = Object.freeze({
   });
    p1.name = "WDY";
    console,log(p1.name);  //undefined
    //在循环中迭代变量时使用三者
    for(var i = 0; i < 5; i++){
   
        console.log(i);  //1,2,3,4,5
    }
    console.log(i);  //5
    
    for(let i = 0; i <5; i++){
   
        console.log(i);  //1,2,3,4,5
    }
    console.log(i);  //未定义
    
    for(const i = 0; i < 5; i++){
   
        console.log(i);  //5,5,5,5,5
    }
    
    for(const i of [1,2,3,4,5]){
   
        console.log(i);  //1,2,3,4,5
    }

变量声明,作用域 -----> ending!

数据类型

JavaScript共有8中数据类型,其中,7种为简单数据类型(原始类型),他们是:Undefined,Null,Number,String,Boolean,Symbol(符号<为ES6新增类型>),BigInt。还有一种复杂数据类型(引用类型):Object。

其中6中简单数据类型属于原始值1种复杂数据类型属于引用值。在讨论数据类型之前,小王现在这里说一下这两种不同类型的数据。

原始值与引用值

保存原始值的变量是按值访问的,而引用值是保存在内存中的对象。
当我们操作原始值时,我们操作的就是存储在变量中的实际值,而当我们操作引用值时,JavaScript不允许直接访问内存的位置,因此我们不能直接操作对象本身所在的内存空间而是操作对该对象的引用。
我认为,这两种类型的区别在变量复制方面的得到了充分地体现:

image.png

image.png
对于原始值,复制之后与复制之前是完全独立的,而对于引用值,复制后的值与复制之前的值指向同一内存空间,所以两者相当于铁索连环啦哈哈哈。

接下来让我们进入今天的正题:

Undefined

undefined即未定义的,其效果如字面意思,当我们使用var/let声明一个变量但未给其赋值时,该变量即为undefined(!注意const可不兴这的搞啊,使用const的前提就是声明的同时必须给其赋值),当然我们也可以给一个变量赋值为undefined但其效果等同于只声明而不赋值:

    let test;
    console.log(test);  //undefined
    
    let test = undefined;
    console.log(test);  //undefined

对于为声明的变量,其返回也是undefined

Null

null即空的,其值表示一个空指针对象,如果我们声明一个变量但未确定给其赋何值时,我们可以将null赋给他,这样当后面我们需要知道这个是否被声明时,只要将其与null比较或者看他数据类型即可,undefined不行吗?undefined不行,因为为声明的值其返回值也可能是undefined。

Boolean

布尔值,只有两个值true和false对于这两个值,有两点需特别注意:

  1. 两个布尔值不等同于数值即true不等于1,false不等于0。
  2. 布尔值区分大小写,虽然True与False也有效,但不能将其认为是布尔值。

布尔值可以通过Boolean()将布尔类型与其他数据类型联系起来:

数据类型 true false
String 非空字符串 “”
Number 非0值 0/NaN
Object 任意对象 Null
Undefined undefined
Null

Number

不同于其他语言,JavaScript的整数和浮点数均为Number,但其存储时使用的内存空间大小不同,存储浮点值使用的内存空间是存储整数值得两倍,所以你懂得(不是很必要的情况就定义为整数)
先说整数:

整数可以由二进制,八进制(0<但是在严格模式下是微小的>),十进制,十六进制(0x)表示。

    let number1 = 070;  //八进制的56
    let number2 = 079;  //无效八进制,会被当做79
    let number3 = 08;   //无效八进制,会被当做8
    let number4 = 0xA;  //十六进制10
    let number5 = 0x1f; //十六进制31

浮点数当小数点后面全为0时会自动转换为整数处理,科学计数法由e表示
千万注意在JavaScript中0.1+0.2 = 0.30000000000000004而不是0.3所以不要测试特定的浮点值

    let number1 = 1.68;
    let number2 = 0.1356;
    let number3 = .123;
    let number4 = 1.0;  //当成1处理

还有一个特殊的数值叫NaN即不是数值(Not a Number)用于表示本来要返回数值的操作失败了。

    0/0;  //NaN

涉及NaN的所有操作始终返回NAN。
注意我不是我即NaN不等于NaN

    console.log(NaN == NaN);   //false

这里有一个方法isNaN()~~(是NaN吗?)~~用于帮我们判断一个值是不是数值。

不仅Boolean类型提供了与其他数据类型联动的方法,Number类型也能与其他数据类型联动Number():

数据类型
Boolean true转换为1,false转换为0
Number 直接返回
null 0
undefined NaN
String 空转换为0
只包含数值,返回数值
除了数值还包含其他字符返回NAN
    let number1 = Number(true);   //1
    let number2 = Number(10);     //10
    let number3 = Number("");     //0
    let number4 = Number(null);   //0
    let number5 = Number(undefined); //NaN
    let number6 = Number("001");  //1

不仅仅是Number(),parseInt()也可以进行转换并且更为常用

    let Number1 = parseInt(true);   //NaN
    let Number2 = parseInt(10);     //10
    let Number3 = parseInt("");     //NaN
    let Number4 = parseInt(null);   //NaN
    let Number5 = parseInt(undefined); //NaN
    let Number6 = parseInt("001");  //1

image.png
可以看出,Number()与parseInt()对于一些类型的转换还是有些许区别的。
此外parseInt()对于Number类型的转化也是杠杠的:

    let number1 = parseInt("0xA");   //10为十六进制数
    let number2 = parseInt("123木头人");  //123
    let number3 = parseInt(3.14159)     //3  碰到非数值字符会停止
    
    //也可以接收两个参数,第二个参数指进制数
    let number4 = parseInt("A",16);  //10
    let number5 = parseInt("10",2);  //2  按二进制解析10
    let number6 = parseInt("10",8);  //8  按八进制解析10

不仅仅有parseInt(),parseFloat()也同样存在,但是parseFloat()只能解析十进制值,因此只传一个参数就可以了。

BIgInt

数字类型number无法表示大于2的53次方减1的和负2的53次方减1的数,而使用BigInt则可以表示任意长度的整数,有两种声明方式:

    let big1 = 123123123123123123123123123123n;   //以n结尾
    let big2 = BigInt("123123123123123123123123123123");  //使用BigInt函数

String

字符串数据类型,可以用单引号(')双引号(")反引号(`)(好东西模板字符串)表示,但开头和结尾的引号必须是同一种引号。

    let name = 'WDY';
    let name = "WDY";
    let name = `WDY`;
字符字面量
字面量 含义
\n 换行
\t 制表
\b 退格
\r 回车
\f 换页
\ 反斜杠
单引号
模板字面量

模板字面量作为ES6中的新功能,使得我们在对变量的组合上更加得心应手:

    let Name = "WDY";
    let Age = "10000";
    let My = "姓名:" + Name + "年龄:" + Age;
    console.log(My);   //姓名:WDY年龄:10000
    let MMy = `姓名:${
     Name}年龄:${
     Age}`;
    console.log(MMy);  //姓名:WDY年龄:10000

同时模板字面量保留了换行字符,可以跨行定义字符串:

    let My = `Name:WDY
    Age:10000`;
    console.log(My);  
    /**Name:WDY
       Age:10000**/;

直接跨行输入即可而不需要输入\n,在使用模板字面量时里面的空格也会存在,因此记得注意格式的美观

模板字面量标签函数

模板字面量支持定义标签函数(标签函数本身是一个常规函数),通过标签函数可以自定义其插值行为:

    const Name = "WDY";
    const age = "10000";
    function get(strings, aVal, bVal, sumVal) {
   
        console.log(strings);
        console.log(aVal);
        console.log(bVal);
        console.log(sumVal);
        return 'ok';
    }
    let my = `姓名:${
     Name},年龄:${
     age}`;
    let My = get`姓名:${
     Name},年龄:${
     age}`;
    console.log(my);
    console.log(My);
    /**[ '姓名:', ',年龄:', '' ]
        WDY
        10000
        姓名:WDY,年龄:10000
        ok
        **/

在标签函数中参数的数量是可变的,所以使用剩余操作符(后面我们会提到)会更加方便:

    const Name = "WDY";
    const age = "10000";
    function get(strings,...expressions){
   
        console.log(strings);
        for(const expression of expressions){
   
            console.log(expression);
        }
        return ok;
    }
    let my = `姓名:${
     Name},年龄:${
     age}`;
    let My = get`姓名:${
     Name},年龄:${
     age}`;
    console.log(my);
    console.log(My);
    /**[ '姓名:', ',年龄:', '' ]
        WDY
        10000
        姓名:WDY,年龄:10000
        ok
        **/

如果想直接得到拼接好的字符串:

    let Name = "WDY";
    let Age = "Age";
    function get(strings,...expressions){
   
        return strings[0] + expressions.map((e,i) => `${
     e}${
     strings[i+1]}`).join('');
    }
    let my = `姓名:${
     Name},年龄:${
     Age}`;
    let My = get`姓名:${
     Name},年龄:${
     Age}`
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值