JavaScript基础总结---重点

JavaScript简介

什么是JavaScript

  • JavaScript 是世界上最流行的语言之一是一种运行在客户端的脚本语言 Script 是脚本的意思
  • 脚本语言不需要编译运行过程中由 js 解释器( js 引擎逐行来进行解释并执行也称为解释型语言不需要被编译为机器码在执行跟C++这种需要被编译的语言不一样
  • 现在也可以基于 Node.js 技术进行服务器端编程

浏览器执行JS过程

浏览器分成两部分渲染引擎和JS 引擎

渲染引擎用来解析HTMLCSS俗称内核比如 chrome 浏览器的 blink 老版本的 webkit

JS 引擎也称为 JS 解释器。 用来读取网页中的JavaScript代码对其处理后运行比如 chrome 浏览器的 V8

浏览器本身并不会执行JS代码而是通过内置 JavaScript 引擎(解释器) 来执行 JS 代码 。JS 引擎执行代码时逐行解释每一句源码转换为机器语言然后由计算机去执行所以 JavaScript 语言归为脚本语言会逐行解释执行。

JS的组成

JavaScript的三大组成部分是ECMAScriptDOMBOM
在这里插入图片描述

ECMAScript

ECMAScript 是由ECMA 国际 原欧洲计算机制造商协会进行标准化的一门编程语言这种语言在万维网上应用广泛它往往被称为 JavaScript 或 JScript但实际上后两者是 ECMAScript 语言的实现和扩展。
ECMAScript 规定了JS的编程语法和基础核心知识是所有浏览器厂商共同遵守的一套JS语法工业标准。

DOM

DOM是文档对象模型Document Object Model的简称。是W3C组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作大小、位置、颜色等。

BOM

BOM 是浏览器对象模型(Browser Object Model)的简称。它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口比如弹出框、控制浏览器跳转、获取分辨率等。

JS的引入方式

1、行内式JS

<input type="button" value="" onclink="javascript:alert('你好')" />
  • 可以将单行或少量JS代码写在HTML标签的事件属性中(以on开头的属性)如 onclink
  • 注意单双引号的使用在HTML中我们推荐使用双引号JS中我们推荐使用单引号
  • 可读性差在 HTML 中编入 JS 大量代码时不方便阅读
  • 特殊情况下使用

2、内嵌式JS

<script>
     alert('你好');
</script>
  • 可以将多行JS代码写到

3、外部JS

<script src="my.js"></script>
  • 利于HTML页面代码结构化把单独JS代码独立到HTML页面之外既美观又方便
  • 引用外部JS文件的script标签中间不可以写代码
  • 适合于JS代码量比较大的情况

函数与作用域

arguments的使用

当我们不确定有多少个参数传递的时候可以用 arguments来获取。在 JavaScript 中arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象arguments 对象中存储了传递的所有实参。
arguments存放的是传递过来的实参
arguments展示形式是一个伪数组因此可以进行遍历。伪数组具有以下特点

  1. 具有 length 属性
  2. 按索引方式储存数据
  3. 不具有数组的 push , pop 等方法
    <script>
        // 当我们不确定有多少个参数传递的时候可以用 arguments 来获取。
        //在 JavaScript 中arguments 实际上它是当前函数的一个内置对象。
        //所有函数都内置了一个 arguments 对象arguments 对象中存储了传递的所有实参。
        // 函数声明
        function fn() {
            console.log(arguments);  //里面存储了所有传递过来的实参
            console.log(arguments.length); // 3
            console.log(arguments[2]); // 3
        }

        // 函数调用
        fn(1,2,3);

        // 利用函数求任意个数的最大值
        function maxValue() {
            var max = arguments[0];
            for (var i = 0; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        console.log(maxValue(1,2,3,4));;
    </script>

全局变量与局部变量

全局变量

  • 在全局作用域下声明的变量叫做全局变量在函数外部定义的变量
  • 全局变量在代码的任何位置都可以使用
  • 在全局作用域下 var 声明的变量 是全局变量
  • 特殊情况下在函数内不使用 var 声明的变量也是全局变量不建议使用

局部变量

  • 在局部作用域下声明的变量叫做局部变量在函数内部定义的变量
  • 局部变量只能在该函数内部使用
  • 在函数内部 var 声明的变量是局部变量
  • 函数的形参实际上就是局部变量

区别
全局变量在任何一个地方都可以使用只有在浏览器关闭时才会被销毁因此比较占内存
局部变量只在函数内部使用当其所在的代码块被执行时会被初始化当代码块运行结束后就会被销毁因此更节省内存空间

<script>
    // 现阶段没有块级作用域{}只有全局和局部es6才新增块级

    // 在C++不行
    // if(3 < 5) {
    //     int num = 10;
    // }
    // cout<<num;

    if(3 < 5) {
        var num = 10;
    }
    console.log(num);


    // 报错局部变量只能在里面使用
    function sort() {
        var num2 = 22;
    }
    console.log(num2);
</script>

预解析

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步预解析和代码执行。
预解析js引擎会把js里面所有的 var 还有 function 提升到当前作用域的最前面

代码执行从上到下执行JS语句

预解析只会发生在通过 var 定义的变量和 function 上。学习预解析能够让我们知道为什么在变量声明之前访问变量的值是 undefined为什么在函数声明之前就可以调用函数。

<script>
    // js引擎会把js里面所有的 var 还有 function 提升到当前作用域的最前面

    // 1.undefined
    console.log(num1);
    var num1 = 11;
    // var num1;
    // console.log(num1);
    // num1 = 11;

    // 2.22
    fun1();
    function fun1() {
        console.log(22);
    }

    // 函数声明       
    // fun1();
    // function函数提升到当前作用域全局最前面声明
    // function fun1() {
    //     console.log(22);
    // }
    
    // 3.报错
    fun2();
    var fun2 = function() {
        console.log(33);
    }
    // var fun2
    // fun2();函数未声明就调用报错
    // fun2 = function() {
    //     console.log(33);
    // }
</script>

对象

创建对象的三种方式

1.利用字面量创建对象

对象字面量就是花括号 { } 里面包含了表达这个具体事物对象的属性和方法
{ } 里面采取键值对的形式表示
键相当于属性名
值相当于属性值可以是任意类型的值数字类型、字符串类型、布尔类型函数类型等

// 1.{}字面量
var obj = {
    name: 'hai',
    sex: '男',
    fun: function() {
        alert('大家好');
    }
}
// 调用对象的方式
console.log(obj.name);
console.log(obj['name']);
obj.fun();

2.利用 new Object 创建对象

var 对象名 = new Object();

var obj2 = new Object();
obj2.name = 'hhh';
obj2.fun2 = function() {
    alert('你好');
}
console.log(obj2.name);
console.log(obj2['name']);
obj2.fun2();

3.利用构造函数创建对象

构造函数 是一种特殊的函数主要用来初始化对象即为对象成员变量赋初始值它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来然后封装到这个函数里面。
使用构造函数要注意以下两点

  1. 构造函数用于创建某一类对象其首字母要大写
  2. 构造函数要和 new 一起使用才有意义
function Star(uname ) {//大写
    this.name = uname;
    this.fun3 = function(sang) {
        console.log(sang);
    }
}
new Star();//空对象
var jjl = new Star('周杰伦');
console.log(typeof jjl);//typeof 运算符返回数据类型
console.log(jjl.name);
jjl.fun3('稻香');

遍历对象属性

for(var k in jjl) {
    console.log(k);//返回属性
    console.log(jjl[k]);//返回属性值
}

变量、属性、函数、方法总结

变量单独声明赋值单独存在
属性对象里面的变量称为属性不需要声明用来描述该对象的特征
函数单独存在的通过“函数名()”的方式就可以调用
方法对象里面的函数称为方法方法不需要声明使用 “对象.方法名()”的方式就可以调用方法用来描述该对象的行为和功能。

new关键字执行过程

new 在执行时会做四件事:

  1. 在内存中创建一个新的空对象。var jjl = new Star('周杰伦');
  2. 让 this 指向这个新的对象。this.name = uname;
  3. 执行构造函数里面的代码给这个新对象添加属性和方法
  4. 返回这个新对象所以构造函数里面不需要return

内置对象

JavaScript 中的对象分为3种自定义对象 、内置对象、 浏览器对象
内置对象就是指 JS 语言自带的一些对象这些对象供开发者使用并提供了一些常用的或是最基本而必要的功能
JavaScript 提供了多个内置对象Math、 Date 、Array、String等

Math对象

Math 是一个内置对象它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。与其他全局对象不同的是Math 不是一个构造器。Math 的所有属性与方法都是静态的。

<script>
    console.log(Math.max(1,2,3));

    // 封装自己的数学对象
    var myMath = {
        max: function () {
            var max = arguments[0];
            for (var i = 0; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
    }
    console.log(myMath.max(1,2,3,4));
    console.log('\n');
    // 取整
    console.log(Math.floor(1.2));//向下取整1
    console.log(Math.floor(1.6));//1
    console.log(Math.ceil(1.2));//向上取整2
    console.log(Math.ceil(1.6));//2
    // 四舍五入
    console.log(Math.round(1.2));//1
    console.log(Math.round(1.6));//2
    console.log(Math.round(-1.2));//-1
    console.log(Math.round(-1.5));//-1特殊.5往大的取
    console.log('\n');
    // 随机数函数 随机返回一个小数其取值范围是 [01)左闭右开 0 <= x < 1表示一种概率
    console.log(Math.random());
    console.log('\n');

    // 得到两个数之间的随机整数并且包含这两个整数(因为左闭右开所以要+1)
    function myRandom(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    console.log(myRandom(1, 10));;

</script>

Date对象

创建一个 JavaScript Date 实例该实例呈现时间中的某个时刻。Date 对象则基于Unix Time Stamp即自 1970 年 1 月 1 日UTC起经过的毫秒数。

  • Date 对象和 Math 对象不一样他是一个构造函数所以我们需要实例化后才能使用
  • 创建一个新Date对象的唯一方法是通过new操作符
  • Date 实例用来处理日期和时间
方法名说明代码
getFullYear()获取当年dObj.getFullYear()
getMonth()获取当月(0-11)dObj.getMonth()
getDate()获取当天日期dObj.getDate()
getDay()获取星期几(周日0到周六6)dObj.getDay()
getHours()获取当前小时dObj.getHours()
getMinutes()获取当前小时dObj.getMinutes()
getSeconds()获取当前秒钟dObj.gerSeconds()
<script>
    // 日期对象Date()  是一个构造函数 必须使用new来调用我们创建的对象
    var arr = new Array();
    // 如果没有输入任何参数则 Date 的构造器会依据系统设置的当前时间来创建一个 Date 对象。
    var date = new Date();
    console.log(date);
    // 参数常用写法1.数字 2.字符串
    // console.log(Date('2022-10-1 20:55:10'));没new实例化不能实现
    var date1 = new Date('2022-10-1 20:55:10');
    console.log(date1);
    console.log('\n');

    var date2 = new Date();
    console.log(date2.getFullYear());
    console.log(date2.getMonth() + 1);//0~11月
    console.log(date2.getDate());
    console.log(date2.getDay());//1~6~0星期天是0
    

    // 封装一个函数返回当前的时分秒 格式 08:08:08
    function getTimer() {
        var time = new Date();
        var h = time.getHours();
        h = h < 10 ? '0' + h : h;
        var m = time.getMinutes();
        m = m < 10 ? '0' + m : m;
        var s = time.getSeconds();
        s = s < 10 ? '0' + s : s;
        return h + ':' + m + ':' + s;
    }
    console.log(getTimer());
</script>

获取时间的总毫秒

<script>
    // 获取Date总的毫秒数 不是当前时间的毫秒数 而是距离1970年1月1号过了多少毫秒数

    // 实例化Date对象
    var date = new Date();

    // 1 .通过 valueOf()  getTime() 用于获取对象的原始值
    console.log(date.valueOf());  //得到现在时间距离1970.1.1总的毫秒数
    console.log(date.getTime());

    // 2.简单的写法
    var date1 = +new Date();  // +new Date()返回的就是总的毫秒数
    console.log(date1);

    // 3. HTML5中提供的方法 获得总的毫秒数 有兼容性问题
    console.log(Date.now());

</script>

倒计时案例

<script>
    function getTimer(time) {
        var end = +new Date(time);
        var now = +new Date();
        var countDown = end - now;
        countDown /= 1000;
        var d = parseInt(countDown / 60 /60 / 24);
        var h = parseInt(countDown / 60 /60 % 24);//取余24进位
        var m = parseInt(countDown / 60 % 60);
        var s = parseInt(countDown % 60);//取余60进位
        return d + '天' + h + '时' + m + '分' + s + '秒';
    }
    console.log(getTimer('2022-10-11 22:43:20'));;
</script>

Array对象

创建Array数组对象的两种方式

  • 字面量方式
  • new Array()

判断是否为数组

两种方法

  1. instanceof运算符可以判断一个对象是否属于某种类型
  2. Array.isArray()用于判断一个对象是否为数组isArray() 是 HTML5 中提供的方法
<script>
    var arr = [];
    var obj = {};
    // 1.instanceof 运算符 检测是否为数组可以翻译为“是”
    console.log(arr instanceof Array);
    console.log(obj instanceof Array);

    // 2.Array.isArray(参数)h5新增方法  IE9以上版本支持
    console.log(Array.isArray(arr));
    console.log(Array.isArray(obj));
</script>

数组排序

方法名说明是否修改原数组
reverse()颠倒数组中元素的顺序无参数该方法会改变原来的数组返回新数组
sort()对数组的元素进行排序该方法会改变原来的数组返回新数组
<script>
    var arr = [3,22,4,1];
    arr.sort()
    console.log(arr);//默认排序顺序是在将元素转换为字符串,22不生效

    // 解决  内联函数  要比较数字而非字符串比较函数可以简单的用 a 减 b如下的函数将会将数组升序排列 反之
    arr.sort(function(a, b) {
        return a - b;
    });
    console.log(arr);
</script>

数组索引

方法名说明返回值
indexOf()数组中查找给定元素的第一个索引如果存在返回索引号如果不存在则返回-1
lastIndexOf()在数组的最后一个索引从后向前索引如果存在返回索引号如果不存在则返回-1

案例数组去重

去除数组[1,2,3,3,4,4]中重复的元素
核心算法我们遍历旧数组然后拿着旧数组元素去查询新数组如果该元素在新数组里面没有出现过我们就添加否则不添加。

<script>
    function unique(arr) {
        var newArray = [];
        for (var i = 0; i < arr.length; i++) {
            if (newArray.indexOf(arr[i])== -1) {//新数组不存在就加入
                newArray.push(arr[i]);
            }
        }
        return newArray;
    }
    var demo = unique([1,2,3,3,4,4]);
    console.log(demo);
</script>

String对象

基本包装类型

为了方便操作基本数据类型JavaScript 还提供了三个特殊的引用类型String、Number和 Boolean。

基本包装类型就是把简单数据类型包装成为复杂数据类型这样基本数据类型就有了属性和方法。例如字符串可以调用length方法求其长度。
把基本数据类型包装为复杂数据类型其执行过程如下

// 1.生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy');
// 2.赋值给我们声明的字符变量
str = temp;
// 3.销毁临时变量
temp = null;

字符串的不可变

字符串里面的值不可变虽然看上去可以改变内容本质是地址变了内存中新开辟了一个内存空间。

var str = 'abc';
str = 'hello';
// 当重新给 str 赋值的时候常量'abc'不会被修改依然在内存中
// 重新给字符串赋值会重新在内存中开辟空间这个特点就是字符串的不可变
var str = '';
for(var i = 0; i < 1000000;  i++){
    str += i;
}
console.log(str);
// 运行出结果需要花费大量时间因为需要不断的开辟新的空间

根据字符返回位置

字符串所有的方法都不会修改字符串本身(字符串是不可变的)操作完成会返回一个新的字符串。

方法名说明
indexOf(‘要查找的字符’开始的位置)返回指定内容在元字符串中的位置如果找不到就返回-1开始的位置是index索引号
lastIndexOf()从后往前找只找第一个匹配的

查找重复字符串案例
查找字符串 "aoooaaoo"中所有o出现的位置以及次数
核心算法先找到第一个o只要str.indexOf('o')不为-1即还有就继续往后找

<script>
    var str = "aoooaaoo";
    var index = str.indexOf('o');
    var num = 0;
    while (index != -1) {
        console.log(index);
        num++;
        index = str.indexOf('o', index + 1);
    }
    console.log(num);
</script>

根据位置返回字符

方法名说明使用
charAt(index)返回指定位置的字符(index字符串的索引号)str.charAt(0)
charCodeAt(index)获取指定位置处字符的ASCII码(index索引号)str.charCodeAt(0)
str[index]获取指定位置处字符HTML,IE8+支持和charAt()等效

判断一个字符串 “aeieeouuee” 中出现次数最多的字符并统计其次数
核心算法利用charAt(index)遍历字符串字符储存给对象最后遍历对象

<script>
    // 有一个对象 来判断是否有该属性 对象['属性名']
    var obj = {
        sex: '男'
    };
    if (obj['sex']) {
        console.log(true);
    } else {
        console.log(false);
    }

    // 判断一个字符串 'aeieeouuee' 中出现次数最多的字符并统计其次数。
    // 利用charAt(index)遍历字符串字符储存给对象最后遍历对象
    var str = "aeieeouuee";
    var o = {};
    for (var i = 0; i < str.length; i++) {
        var chars = str.charAt(i);
        if (o[chars]) { //如果字符存在属性值加加
            o[chars]++;
        } else {
            o[chars] = 1; 
        }
    }
    console.log(o);
    // 遍历对象
    var max = 0;
    var ch = '';
    for (var k in o) {
        if (o[k] > max) {
            max = o[k];
            ch = k;
        }
    }
    console.log(max);
    console.log('最多的字符是' + ch);
</script>

字符串操作方法

方法名方法名 说明
concat(str1,str2,str3…)用于连接两个或对各字符串。拼接字符串
substr(start,length)从 start 位置开始(索引号), length 取的个数。
slice(start,end)从 start 位置开始截取到 end 位置 end 取不到 (两个都是索引号)
substring(start,end)从 start 位置开始截取到 end 位置 end 取不到 (基本和 slice 相同但是不接受负)
replace(被替换的字符,要替换为的字符串)在字符串中用一些字符替换另一些字符
split(‘分隔符’)将字符串切分为数组
<script>
    // 连接与截取
    var str = '1234';
    console.log(str.concat('456')); //1234456
    console.log(str.substr(2, 2)); //34

    // 替换
    console.log(str.replace('1', '0')); //0234
    // 替换所有e
    var str2 = 'aeeeiou';
    while (str2.indexOf('e') != -1) { //只要存在就替换
        str2 = str2.replace('e', 'E');
    }
    console.log(str2); //aEEEiou

    // 切分字符串为数组 对比 join把数组转换为字符串
    var str3 = '1,2,3,4';
    console.log(str3.split(',')); //['1', '2', '3', '4']
</script>

简单类型与复杂类型

简单类型又叫做基本数据类型或者值类型复杂类型又叫做引用类型

基本数据类型在存储时变量中存储的是值本身如
string numberbooleanundefinednull
引用类型复杂数据类型在存储时变量中存储的仅仅是地址引用如
通过 new 关键字创建的对象系统对象、自定义对象如 Object、Array、Date等

不同的内存分配

简单类型
变量的数据直接存放在变量即栈空间中

引用类型
栈空间里存放的是地址真正的对象实例存放在堆空间中栈的地址指向堆区的对象

不同类型传参的区别

知道了数据不同的内存分配那么参数传递的变量也是不一样的简单类型传参是把一个值复制给了形参那么在方法内部对形参做任何修改都不会影响到的外部变量。
而把引用类型变量传给形参时其实是把变量在栈空间里保存的堆地址复制给了形参形参和实参其实保存的是同一个堆地址所以操作的是同一个对象。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: JavaScriptJava