Javascript基础知识(2)

本文详细介绍了JavaScript中的算术运算符、递增递减运算符、比较运算符、逻辑运算符及其用法。讨论了浮点数精度问题,以及变量的赋值和比较。此外,还涵盖了条件表达式、分支结构如switch语句和循环结构。重点讲解了函数的声明、调用、参数、返回值和arguments对象。最后,简述了作用域、变量提升和预解析的概念,以及对象的创建和遍历。内容深入浅出,适合初学者巩固JavaScript基础知识。

操作符

  • 算术运算符
    在这里插入图片描述

浮点数的最高精度是17位小数,因此不要直接判断两个浮点数是否相等

var result = 0.1 + 0.2;    // 结果不是0.3,而是:0.30000000000000004
console.log(0.07 * 100);   // 结果不是7,而是:7.000000000000001
  • 递增递减运算符

前置递增和后置递增运算符可以简化代码的编写,让变量的值+ 1 比以前写法更简单
单独使用时,运行结果相同
与其他代码联用时,执行结果会不同
后置:先原值运算,后自加(先人后己)
前置:先自加,后运算(先已后人)
开发时,大多使用后置递增/减,并且代码独占一行,例如:num++; 或者num–

        var a = 10;
        ++a; // ++a  11    a = 11
        var b = ++a + 2; // a = 12   ++a = 12
        console.log(b); // 14

        var c = 10;
        c++; // c++ 11  c = 11
        var d = c++ + 2; //  c++  = 11     c = 12
        console.log(d); // 13

        var e = 10;
        var f = e++ + ++e; // 1. e++ =  10  e = 11  2. e = 12  ++e = 12
        console.log(f); // 22
        // 后置自增  先表达式返回原值 后面变量再自加1
  • 比较运算符

在这里插入图片描述

注意两个判断和全等的区别,判断是两边值是否相等,有隐式装转换。全等是判断值和数据类型是否完全相同。一般来说后期都是用全等。

  • 逻辑运算符

在这里插入图片描述

返回值是布尔类型。接下来介绍逻辑中断运算法,原理是当有多个表达式的值时,左边的表达式可以确定结果时,就不再继续运算右边的表达式的值

逻辑与 表达式1 && 表达式2
如果第一个表达式的值为真,则返回表达式2
如果第一个表达式的值为假,则返回表达式1

console.log( 123 && 456 );  // 456
console.log( 0 && 456 ); // 0
console.log( 123 && 456&& 789 );  // 789

逻辑或:表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1
如果第一个表达式的值为假,则返回表达式2

console.log( 123 || 456 );  //  123
console.log( 0 ||  456 ); //  456
console.log( 123 || 456 || 789 );  //  123
  • 赋值运算符
    在这里插入图片描述
  • 运算符优先级
    在这里插入图片描述

分支

  • 流程控制
    在这里插入图片描述
  • 三元表达式

表达式1 ?表达式2 :表达式3;
如果表达式1为true ,则返回表达式2的值,如果表达式1为false,则返回表达式3的值
简单理解:就类似于if else (双分支)的简写

var time = prompt('请您输入一个0 ~ 59 之间的一个数字');
// 三元表达式表达式?表达式1 :表达式2 
var result = time < 10 ? '0' + time : time; // 把返回值赋值给一个变量alert(result);

  • 分支流程控制switch语句
switch( 表达式){ 
case value1:
// 表达式等于value1 时要执行的代码
break;
case value2:
// 表达式等于value2 时要执行的代码
break;
default:
// 表达式不等于任何一个value 时要执行的代码
}

循环(与其他编程语言完全一样)

  • for循环
  • 双重for循环
  • while循环
  • do while循环
  • continue break

数组

  • 创建数组的两种方式

利用new创建数组
利用数组字面量创建数组

var arr = new Array();// 创建一个新的空数组
//2. 使用数组字面量方式创建带初始值的数组
var  数组名= ['小白','小黑','大黄','瑞奇'];
//数组中可以存放任意类型的数据,例如字符串,数字和布尔值
  • 获取数组元素
// 定义数组
var arrStus = [1,2,3];
// 获取数组中的第2个元素
alert(arrStus[1])
  • 遍历数组
var arr = ['red','green', 'blue'];
for(var i = 0; i < arr.length; i++){console.log(arrStus[i]);}

  • 数组中新增元素

通过修改length长度新增数组元素或者修改数组索引

var arr = ['red', 'green', 'blue', 'pink'];
arr.length=7;
console.log(arr);
console.log(arr[4]);
console.log(arr[5]);
console.log(arr[6]);

//采用直接追加的方式
var arr = ['red', 'green', 'blue', 'pink'];
arr[4] = 'hotpink';
console.log(arr);

其中索引号是4,5,6 的空间没有给值,就是声明变量未给值,默认值就是undefined。
在这里插入图片描述

  • 数组案例(冒泡排序代码)
var arr = [5, 4, 3, 2, 1];
for (var i = 0; i < arr.length -1; i++) 
{
    for (var j = 0; j < arr.length -i -1; j++) 
      {  
          if (arr[j] > arr[j + 1]) 
         { 
             var temp = arr[j];
             arr[j] = arr[j + 1];
             arr[j + 1] = temp;
          }
      }
 }
  console.log(arr);

函数

  • 使用

声明和调用函数,function是声明函数的关键字,必须小写由于函数一般是为了实现某个功能才定义的,所以通常我们将函数名命名为动词,比如getSum

// 声明函数
function 函数名() 
{//函数体代码}
函数名();// 通过调用函数名来执行函数体代码
  • 参数

形参和实参,在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参,而在调用该函数时,同样也需要传递相应的参数,这些参数被称为实参。需要注意的是JS允许函数形参和实参的个数出现不匹配的问题。

在这里插入图片描述

function sum(num1, num2) {
  console.log(num1 + num2);
}
 sum(100, 200);// 形参和实参个数相等,输出正确结果
 sum(100, 400, 500, 700);//实参个数多于形参,只取到形参的个数
 sum(200);//实参个数少于形参,多的形参定义为undefined,结果为NaN
  • 返回值

在使用return 语句时,函数会停止执行,并返回指定的值
并且return语句后的代码并不会被执行
并且return只能返回一个值,如果写多个值的话,以最后一个为准
如果函数没有return ,返回的值是undefined

  • arguments

当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。

arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点。
具有length属性
按索引方式储存数据
不具有数组的push,pop等方法

利用函数求任意个数的最大值

function maxValue() {
      var max = arguments[0];
      for (var i = 0; i < arguments.length; i++) {
          if (max < arguments[i]) {
                     max = arguments[i];
          }
      }
      return max;
}
console.log(maxValue(2, 4, 5, 9))
;console.log(maxValue(12, 4, 9))
  • 两种声明方式

命名函数
利用函数关键字function自定义函数方式,调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面

// 声明定义方式
function fn() {...}
// 调用
fn();

匿名函数
又称为函数表达式原理和声明变量是一致的,函数调用的代码必须写到函数体后面

// 这是函数表达式写法,匿名函数后面跟分号结束
var fn = function(){...}// 调用的方式,函数调用必须写到函数体下面
fn();

作用域

  • 作用域

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

全局作用域和局部作用域(ES6之前)但是JS没有块级作用域。
一般来说在if语句,循环中创建的变量,仅仅只能在本if语句中使用,比如下面的Java代码

if(true){
    int num = 123;
    system.out.print(num);  //123
 }
 system.out.print(num); //报错
if(true){
   var num = 123;
   console.log(123); //123
}
console.log(123);  //123
  • 变量的作用域

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
全局变量在代码的任何位置都可以使用
在全局作用域下var 声明的变量是全局变量
特殊情况下,在函数内不使用var 声明的变量也是全局变量(不建议使用)
在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间
在函数内部var 声明的变量是局部变量
函数的形参实际上就是局部变

  • 作用域链

采取就近原则的方式来查找变量最终的值

        // 作用域链  : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链   就近原则
 // 案例1 : 结果是几?
        function f1() {
            var num = 123;

            function f2() {
                var num = 0;
                console.log(num); // 站在目标出发,一层一层的往外查找0
            }
            f2();
        }
        var num = 456;
        f1();

        // 案例2 :结果是几?
        var a = 1;

        function fn1() {
            var a = 2;
            var b = '22';
            fn2();

            function fn2() {
                var a = 3;
                fn3();

                function fn3() {
                    var a = 4;
                    console.log(a); //a的值 4
                    console.log(b); //b的值 '22'
                }
            }
        }
        fn1();

预解析

  • 预解析 我们先来看一些常见错误案例
        // 1问  
        console.log(num); //报错



        // 2问
        console.log(num); // undefined  坑 1
        var num = 10;
        // 相当于执行了以下代码
        // var num;
        // console.log(num);
        // num = 10;



        // 3问  
        fn();//正常
        function fn() {
            console.log(11);
        }
     




        // 4问
        fun(); // 报错  坑2 
        var fun = function() {
                console.log(22);

            }
            // 函数表达式 调用必须写在函数表达式的下面
            // 相当于执行了以下代码
            // var fun;
            // fun();
            // fun = function() {
            //         console.log(22);

        //     }
        // 1. 我们js引擎运行js 分为两步:  预解析  代码执行
        // (1). 预解析 js引擎会把js 里面所有的 var  还有 function 提升到当前作用域的最前面
        // (2). 代码执行  按照代码书写的顺序从上往下执行
        // 2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
        // (1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面  不提升赋值操作
        // (2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面  不调用函数

JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行。
预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有var 和function 声明的变量在内存中进行提前声明或者定义。
代码执行:从上到下执行JS语句。预解析只会发生在通过var 定义的变量和function 上。

  • 变量预解析与函数预解析

变量提升:变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升(案例同上)
函数提升:函数的声明会被提升到当前作用域的最上面,但是不会调用函数(案例同上)

经典案例1

        // 案例1
        var num = 10;
        fun();

        function fun() {
            console.log(num);//undefined
            var num = 20;
        }
        // 相当于执行了以下操作
        // var num;

        // function fun() {
        //     var num;
        //     console.log(num);
        //     num = 20;
        // }
        // num = 10;
        // fun();

经典案例2

        var num = 10;

        function fn() {
            console.log(num); //undefined
            var num = 20;
            console.log(num); //20
        }
        fn();
        // 相当于以下代码
        // var num;

        // function fn() {
        //     var num;
        //     console.log(num);
        //     num = 20;
        //     console.log(num);
        // }
        // num = 10;
        // fn();

经典案例3

        var a = 18;
        f1();

        function f1() {
            var b = 9;
            console.log(a); //undefined
            console.log(b); //9
            var a = '123';
        }
        // 相当于以下代码
        // var a;

        // function f1() {
        //     var b;
        //     var a;
        //     b = 9;
        //     console.log(a);
        //     console.log(b);
        //     a = '123';
        // }
        // a = 18;
        // f1();

经典案例4

        f1();
        console.log(c); //9
        console.log(b); //9
        console.log(a); //9

        function f1() {
            var a = b = c = 9;
            console.log(a); //9
            console.log(b); //9
            console.log(c); //报错
        }
        // 以下代码
        // function f1() {
        //     var a;
        //     a = b = c = 9;
        //     // 相当于 var  a  = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
        //     // 集体声明  var a = 9, b = 9, c = 9;
        //     console.log(a);
        //     console.log(b);
        //     console.log(c);
        // }
        // f1();
        // console.log(c);
        // console.log(b);
        // console.log(a);

对象

  • 对象

在JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成,属性是事物的特征,方法是事物的行为

  • 创建对象的三种方式

在JavaScript中,现阶段我们可以采用三种方式创建对象(object

利用字面量创建对象
对象字面量:就是花括号{ } 里面包含了表达这个具体事物(对象)的属性和方法。{ } 里面采取键值对的形式表示

        // 1.利用对象字面量创建对象 {}
        // var obj = {};  // 创建了一个空的对象 
        var obj = {
                uname: '张三疯',
                age: 18,
                sex: '男',
                sayHi: function() {
                    console.log('hi~');

                }
            }
            // (1) 里面的属性或者方法我们采取键值对的形式  键 属性名 : 值  属性值 
            // (2) 多个属性或者方法中间用逗号隔开的
            // (3) 方法冒号后面跟的是一个匿名函数
            // 2. 使用对象
            // (1). 调用对象的属性 我们采取 对象名.属性名 . 我们理解为 的
        console.log(obj.uname);
        // (2). 调用属性还有一种方法 对象名['属性名']
        console.log(obj['age']);
        // (3) 调用对象的方法 sayHi   对象名.方法名() 千万别忘记添加小括号
        obj.sayHi();
        // 变量 单独声明并赋值  使用的时候直接写变量名 单独存在
        // 属性 在对象里面的不需要声明的 使用的时候必须是 对象.属性
        // 2. 函数和方法的相同点 都是实现某种功能  做某件事
        // 函数是单独声明 并且调用的 函数名() 单独存在的
        // 方法 在对象里面 调用的时候 对象.方法()

利用new Object 创建对象

        // 利用 new Object 创建对象
        var obj = new Object(); // 创建了一个空的对象
        obj.uname = '张三疯';
        obj.age = 18;
        obj.sex = '男';
        obj.sayHi = function() {
                console.log('hi~');

            }
            // (1) 我们是利用 等号 = 赋值的方法 添加对象的属性和方法
            // (2) 每个属性和方法之间用 分号结束
        console.log(obj.uname);
        console.log(obj['sex']);
        obj.sayHi();

利用构造函数创建对象

       // 我们为什么需要使用构造函数
        // 就是因我们前面两种创建对象的方式一次只能创建一个对象
        var ldh = {
            uname: '刘德华',
            age: 55,
            sing: function() {
                console.log('冰雨');

            }
        }
        var zxy = {
                uname: '张学友',
                age: 58,
                sing: function() {
                    console.log('李香兰');

                }
            }
            // 因为我们一次创建一个对象,里面很多的属性和方法是大量相同的 我们只能复制 
            // 因此我们可以利用函数的方法 重复这些相同的代码 我们就把这个函数称为 构造函数
            // 又因为这个函数不一样,里面封装的不是普通代码,而是 对象  
            // 构造函数 就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
        // 利用构造函数创建对象
        // 我们需要创建四大天王的对象  相同的属性: 名字 年龄 性别  相同的方法: 唱歌
        // 构造函数的语法格式
        // function 构造函数名() {
        //     this.属性 = 值;
        //     this.方法 = function() {}
        // }
        // new 构造函数名();
        function Star(uname, age, sex) {
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function(sang) {
                console.log(sang);

            }
        }
        var ldh = new Star('刘德华', 18, '男'); // 调用函数返回的是一个对象
        // console.log(typeof ldh);
        console.log(ldh.name);
        console.log(ldh['sex']);
        ldh.sing('冰雨');
        var zxy = new Star('张学友', 19, '男');
        console.log(zxy.name);
        console.log(zxy.age);
        zxy.sing('李香兰')



        // 1. 构造函数名字首字母要大写
        // 2. 我们构造函数不需要return 就可以返回结果
        // 3. 我们调用构造函数 必须使用 new
        // 4. 我们只要new Star() 调用函数就创建一个对象 ldh  {}
        // 5. 我们的属性和方法前面必须添加 this

构造函数抽象了对象的公共部分,封装到了函数里面,它泛指一个大类class
创建对象特指某一个,通过new关键字创建对象的过程我们也称为对象实例化

  • new关键字
  1. 在内存中创建一个新的空对象。
  2. 让this指向这个新的对象。
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法。
  4. 返回这个新对象(所以构造函数里面不需要return)
  • 遍历对象属性
        // 遍历对象 
        var obj = {
                name: 'happy',
                age: 18,
                sex: '男',
                fn: function() {}
            }
            // console.log(obj.name);
            // console.log(obj.age);
            // console.log(obj.sex);
            // for in 遍历我们的对象
            // for (变量 in 对象) {

        // }
        for (var k in obj) {
            console.log(k); // k 变量 输出  得到的是 属性名
            console.log(obj[k]); // obj[k] 得到是 属性值

        }
        // 我们使用 for in 里面的变量 我们喜欢写 k  或者  key
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清辞-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值