前言

本文介绍JavaScript的基础语法,主要记录自己学习JavaScript的过程,内容可能有些许错乱、不够完善。


基础部分

这部分是博主初学JavaScript的随笔记录,放到此处。可以直接跳转到数据类型

数据类型

  • 值的类型:null(空)、undefined(未定义)、string(字符串)、number(数字)、Boolean(布尔值)、Symbol(符号)。

  • 引用值:function()、Array(数组)、Object(对象)。

需要了解的运算符、关键字和保留字

其他基础

  • <a href="javascript:;"></a>阻止刷新

  • 只要是有” “会变成string,例如”undefined1”为字符串。

  • 选择器嵌套:

1
var div=document.getElementsByClassName[index].getElementByTagName('div'
  • %代表为余数

  • if(变量名)判断是否有值,(下图中被认定为false)。

  • [] 里面可以放几个[{},0,”数组”],{,},()变量(键名,键值)。

  • 设置多个style

1
2
3
4
5
6
7
// 例如:
div.style='color:green;background:cyan;'
document.getElementById("hello").style.color = "blue";

// Jquery设置样式
$("p").css("color", "red");
$("p").css({"color":"red", "font-size":"20px"});
交换两个变量的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var a = 123
var b = 234

var c = b
b = a
a = c
//第一种交换变量值

// a = a + b
// b = a - b
// a = a - b
//第二种交换变量值,为浮点数有一定问题。
//或者
// b = a + (a = b) - b

// b = a + (a = b , 0)
// 第三种交换
console.log(a,b)
封装一个选择器函数
1
2
3
function $(x) {
return document.getElementById(x)
}
for循环

for in循环,下图中key为键名,输出键值[key]

1
2
3
4
5
var person = {name: "Aaron Ryuu", age: 30};
for (key in person) {
console.log(key)
console.log(person[key]);
}

如下,点击事件输出的i为demo.leagth,(即为最后的个数),var换成let可以解决,或者闭包。

1
2
3
4
5
6
7
for (var i = 0; i < 4; i++) {
(function (i) {
demo[i].onclick = function () {
console.log(i)
}
})(i)
}

当i = 0时,demo[0].onclick = function(){alert(i)}i++

当i = 1时,demo[1].onclick = function(){alert(i)}i++

当i = 2时,demo[2].onclick = function(){alert(i)}i++

当i = 3时,demo[3].onclick = function(){.alert(i)}i++

当i = 4时,不满足条件跳出循环。

1
2
3
4
5
6
for (var i = 0; i < 4; i++) {
console.log(i)
$("demo")[0].onclick = function () {
console.log(i)
}
}

for里面的var是全局变量,文档全部可以使用。

1
2
3
4
for (var i = 0; i < 4; i++) {
console.log(i)//输出0,1,2,3
}
console.log(i)//输出4
判断整数

判断整数:if(isNaN(填:val))

时间:var now = new Date();

switch
1
2
3
4
5
6
7
8
9
var day = new Date().getDay();
var today;
switch (day) {
case 1:
today = "某某";
break;
default:
today = "某某";
}
字符串

charCodeAt里转化大于255的为中文(2字节),否则是英文(1字节)。

字符串中间的空格也会算一个索引值。

  • js逐行解析

  • 1字节(B)=8bit(比特);

  • ECMAScript(标准语法)、Dom(文档对象模型)、Bom(浏览器对象模型);

  • prompt()输入框。用户可以输入;

变量

变量是一个容器,var x = 1 ,声明加赋值一起是变量的初始化;

不要var会是全局变量;不加,会导致下面的是全局变量;

1
2
3
4
5
// 同时声明多个变量
var age = 18,
address = '火影',
gz = 2000
console.log(age, address, gz)

变量名:变量严格区分大小写,不能数字开头;使用英语单词,不要使用name;


数据基础

js 的变量数据类型是只有程序在运行过程中,根据等号右边的值来确定的,是动态变化的;

数字性

以0开头的为8进制(如:var num =010);十六进制0~9a~f0x9);

1
2
3
4
5
6
7
8
9
10
11
12
// 最大值
console.log(Number.MAX_VALUE)
// 最小值
console.log(Number.MIN_VALUE)
//无穷大Infinity
console.log(Number.MAX_VALUE * 2)
//无穷小-Infinity
console.log(-Number.MAX_VALUE * 2)
//非数字NaN
console.log('pink' - 10)
//isNaN(),返回true和false
console.log(isNaN(1))

字符串

字符串的引号选择就近原则

转义符:需要\开头

\n 换行
\ 斜杠\
' ‘单引号
" ”双引号
\t tab,缩进
\b 空格,blank
1
2
3
4
5
// 外面单双引号都可以
var str ='我是"默谐"'
var str1 ="我是'默谐'"
console.log(str)
console.log(str1)
  • Boolern:true=1,false=0;可用与相加;

  • typeof可以用来判断变量的类型。

  • null的typeof输出为object;

1
2
var num = 1
console.log(typeof num)

数据类型转化:

1
2
3
var num = prompt("请输入年龄")
console.log(typeof num)
// 输出为字符串
  • 转化为字符串(如下3种方法)
1
2
3
4
5
var z = 1
var z1 = z.toString()
var z2 = String(z)
var z3 = 1 + ""
console.log(typeof z,typeof z1,typeof z2,typeof z3)
  • 转化为数字

input也是字符串,需要转化成整数或者浮点数;

parseInt();parseFloat();Number();隐式转化- * /三个;

1
2
3
4
5
6
// 保留两位小数toFixed
var a = "165.65141"
console.log(parseFloat(a).toFixed(2))
// parseInt第二个参数
parseInt(string, radix)
// 表示前面字符串按照几进制转化成10进制(范围2-3)
  • 转化为布尔型

  • 使用Boolean(),0 NaN null undefined " " 这五个会转化为false,其他为true

  • 强转布尔值!!

1
2
3
4
5
6
7
var arr = new Array(6)
arr[0] = "10"
arr[1] = "5"
arr[2] = "40"
arr[3] = "25"
arr[4] = "1000"
arr[5] = "1"

转化数组:

  • split其中()、(’’)、(’ ‘)、(’ , ‘)的区别;第一种是转化为一个数组、加引号是每个字符串一个数组、空格和逗号是用什么分割开字符串后再排除这分割符号转化数组的意思。(如果字符串中间没有空格和逗号使用后面两个,会和第一种一样);

  • join其中()、(’’)、(’ ‘)、(’ , ‘)的区别;第一种是默认数组中几个用,隔开,第二种是直接相连、最后两个是几个用空格隔开和用逗号隔开,最后的与第一个相同。

1
2
3
//  split()
var color = "red,blue,yellow";
console.log(color.split());

数组

sort排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var values = [1, 5, 20, 3, 9];

function a(a, b) {
if (a < b) {
return 1 //排在后面
} else if (a > b) {
return -1 //排在前面
} else {
return 0;
}
}
//第二种(推荐)
function b(a, b) {
return a - b //倒序b-a
}

console.log(values.sort(a))
console.log(values.sort(b));

数组循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var nums = [1, 2, 3, 4, 5];
nums.forEach(function (item, index, array) {
console.log(item)
})
console.log(nums[3])

for (var i = 0; i < nums.length; i++) {
console.log(nums[i])
}

// 使用map可以直接用var,可以直接返回;
var result = nums.map(function(item, index, array) {
return item * 2;
})

console.log(result);

其他

  • 时间加new是一个对象,不加是一个字符串,会导致它的时间对象的方法不能使用。

  • 除了getDate()中的月的第几天,(从1开始);其他是从零开始,如:月的索引值是0开始,判断月份注意;

  • value得到的是字符串,需要转化为数字,才能运算。

  • return返回值时不能加var

  • 如何解决:在span内加上style属性(样式)word-break:break-all;可以让英文自动换行;

  • 再封装选择器函数时,使用return返回函数里面的变量,不能返回这个,需要返回具体的表示的那个。

  • 使用document.querySlectorALL的方法,获取的也是数组;

三元表达式

1
2
var offsetLeft
step = step > 0 ? Math.ceil(step) : Math.floor(step)
  • 使用截流的是下面的赋值需要放到if里面;

  • 写轮播图是注意index++不要写到定时器的里面了;(图片的offsetLeft页面缩放会影响,放大不会)

  • indexOf字符串索引值的位置,lastIndexOf是从后往前搜索字符串,找到索引值位置;(数组同理)

元素外部插入节点:

使用原生js在元素外部插入可以使用insertBefore先找到父级,再将第二个参数填要插入的节点;

或者使用insertAdjacentHTML来插入,但是不能使用document.createElement(“li”)来创建节点,直接创建;

如果是克隆,或者上面的某个,目前只知道能使用第一种;


运算符

算数运算符:+ - * / %;浮点数运算有精度问题(避开浮点数运算),不要用来相比较;**次方;

表达式和返回值:var num = 1 + 1;

前置运算符,后置运算符,++num、num++;只能配合变量使用;

1
2
3
4
5
6
7
8
9
// 单独使用效果相同,前置是先自加,后返回值;
var age = 20
console.log(++age + 10) // 31
// 后置先返回原值,后自加
var age = 20
console.log(age++ + 10) // 30
console.log(age) // 31
// 注意age赋值
console.log(age++ + age++) // 41

比较运算符:== !=;=== !==

  • 逻辑运算符:&& || !

    1. 逻辑&&两侧都为true,结果是true,一侧为false就是false;
    2. 逻辑||两侧都为false,结果是false,一侧为true就是true;
  • 短路运算:值或者表达式参与逻辑运算;当有多个表达式值时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值;(好像:boolearn不影响)

1
2
3
4
5
6
7
8
9
10
11
// 逻辑与&&短路运算;(“找假”);逻辑或||短路运算;(“找真”)
// 如果表达式1结果为真,则返回表达式2
// 如果表达式1结果为假,则返回表达式1
console.log(123 && 456) // 456
console.log(0 && 456) // 0
console.log(1 && 5 && 2) // 2
console.log(1 && 0 && 2) //0
// 逻辑中断,影响程序运行结果;
var num = 1
console.log(123 || num++) // 123
console.log(num) // 0

赋值运算符:+= -= *= /= %=;原理同+=

运算符优先级:

循环

for循环

  1. 首先执行里面的计数器变量var i = 1,但是这句话只执行一次;

  2. 去i <=100来判断是否满足条件,满足执行循环体,不满足退出循环;

  3. 执行i ++,递增第一轮结束;

  4. 接着去执行i<=100,满足执行循环体,不满足退出循环;

断点调试:

浏览器选择Sources,选择要测试的文件,之后点击代码左边那行断点,刷新页面即可,右上角可以选择下一步、上一步等调试工具;

1
2
3
4
5
6
7
8
9
// 打印10行递减三角形
var str = '';
for (var i = 0; i <= 10; i++) {
for (var j = i; j <=10; j++) {
str = str + '⭐'
}
str += '\n'
}
console.log(str)
1
2
3
4
5
6
7
8
9
// 打印9*9乘法表
var str = '';
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
str += j + '*' + i + '=' + j * i + '\t'
}
str += '\n'
}
console.log(str)

while

  • while do循环至少执行一次,先执行再判断;(适合判断循环条件复杂使用)

  • continue是跳出本次循环直接跳到i++,继续执行剩余的循环;break退出整个循环;

1
2
3
4
5
6
for (var i=1;i<=5;i++){
if(i===3){
continue
}
console.log(i) // 结果为 1 2 4 5,没有3
}

数组方法

数组创建方式:

1
2
3
4
// 利用new创建
var arr = new Array();
// 利用数组字面量创建数组[]
var arr = []

数组转换成字符串

1
2
3
4
5
6
7
var arr = [1, 2, 3];
var str = '';
var sep = '!'
for (var i = 0; i < arr.length; i++) {
str += arr[i] + sep
}
console.log(str)

数组新增元素

1
2
3
4
5
var arr = [1, 2, 3]
arr.length = 5;
console.log(arr[3]) // undefined
arr[3] = 4
console.log(arr[3]) // 4,可以用来新增和替换;

冒泡排序

1
2
3
4
5
6
7
8
9
10
11
var arr = [1, 5, 4, 3, 2]
for (var i = 0; i < arr.length - 1; i++) { // 循环管趟数,每次循环后将取一个最大值放后面;
for (var j = 0; j < arr.length - 1 - i; j++) { // 循环管次数
if (arr[j] > arr[j + 1]) {
var temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
console.log(arr)

函数

  • (()=>{console.log(this)})() 输出为Window

  • 封装函数实参和形参不匹配问题:

    1. 如果实参个数多余形参,则会取形参的个数;
    2. 如果实参个数少余形参,(相相当于后面的形参只是声明没有赋值,为undefined,NaN,拼接其他);
  • 函数返回return(for循环不可以写)return只能返回一个值,有多个值用逗号隔开会返回最后的一个;

  • 函数没有return返回值则是undefined;

arguments:

所有函数都内置arguments对象,其中存储了传递的 所有实参。

一个伪数组并不是真正的数组;特点:有数组的length属性,按照索引的方式进行存储的,没有真正数组的一些方法 pop()、push()等等

1
2
3
4
5
6
7
8
9
// 反转数组
function reverse(arr) {
var newArr = []
for (var i = arr.length-1; i >= 0; i--) {
newArr[newArr.length]=arr[i]
}
return newArr
}
console.log(reverse([1, 2, 3, 4, 5]))
  • 判断闰年算法:能被四整除且不能被100整除,或者能被400整除;(如:2100年)

  • 函数2种声明方式:①(命名函数)function name(){};②(匿名函数)var name= function(){},name是变量名,不是函数名;

作用域

定义:某个代码名字(变量)起作用和效果;

全局变量:只有再浏览器关闭的时候才会销毁,比较占内存资源;

局部变量:当我们程序执行完毕就会销毁,比较节约内存资源;

js没有块级作用域:ES6新增了;就是{}里面定义的变量如if中,外面可以读取到;

作用域链:内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个之值;内部函数不能直接调用,函数内部声明的函数,调用外部函数但是想要触发里面函数定义的变量等,必须先在外部函数里面调用这个内部函数;(多个函数嵌套,也是需要外部的调用里面的,一级一级调用才会生效)

js预解析

js解析器先预解析再代码执行;

1
2
3
4
5
// var f1
f1() // 报错
var f1 = function () {
console.log(1111)
}
  1. js里面的所有var,function提升到当前作用域的最前面;

  2. 执行代码,从上往下;

  • 变量提升就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作;

  • 函数提升就是把所有的函数声明提升到当前的作用域最前面,不调用函数;


对象导读

创建对象的三种方式

  1. 利用字面量创建对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 创建对象
    var obj = {
    attribute: 'value',
    age: 22,
    action: function(){}
    }
    // 删除对象属性
    delete obj.age
    // 调用属性
    console.log(obj.attribute)
    console.log(obj['attribute'])
    obj.action()
  2. 利用 new Object 创建对象

    1
    var obj = new Object()
  3. 利用构造函数创建对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 可以一次创建多个对象,调用时返回的是一个对象
    function Star(uname,age){
        this.name = uname
        this.age = age
    this.sing = function(sing){
            console.log(sing);
        }
    }
    var star = new Star('DWS',22);
    console.log(star.name);
    star.sing('冰雨');
    // 构造函数首字母大写(规范)
    // 构造函数不需要返回值,就可以打印
    // 调用构造函数必须使用new

①构造函数泛指某一大类;②对象特指具体的事物(实例);③我们利用构造函创建对象的过程称为对象的实例化;

  1. new关键字

    1. 在内存中创建一个新的空对象;
    2. 让this指向这个新的对象;
    3. 执行构造函数里面的代码,给这个新对象添加属性和方法;
    4. 返回这个新对象(所以构造函数里面不需要return)。
  2. 遍历对象

    1
    2
    3
    4
    5
    var obj = {name: "DWS", age: 22};
    for (key in obj) {
        console.log(key);
       console.log(obj[key]);
    }

内置对象

JS 语言自带的一些对象,提供了一些常用的或是最基本而必要的功能(属性和方法)

Math对象

使用时不需要new,对象不是构造函数,它具有数学常数和函数的属性和方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Math.PI // 圆周率
Math.floor() // 向下取整
Math.ceil() // 向上取整
Math.round() // 四舍五入
Math.abs() // 绝对值
Math.max()/Math.min() // 求最大和最小值
Math.random() // 一个浮点数的随机数在范围[0,1)

// 注意
Math.round() // 就近取整 注意 -3.5 结果是 -3,.5往大的取值
Math.abs(' -1 ') // 结果为1,隐式转换;
Math.max()/Math.min() // 直接console.log输出Infinity

function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;// 两数之间的随机数,min <= x < max;
}
function getRandom(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值;
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 ;
}

日期对象

Date是一个构造函数,所以我们需要实例化后才能使用

1
2
3
4
5
6
7
// Date()方法的使用
// 里面可以跟参数得到的为参数时间,字符串为('2021-11-18 14:21:00'),数字(2021,11,18)
var now = new Date();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
var day = date.getDay()
console.log(arr[day])
// 注意,月份是从0开始,周日是0,周一是1;

1
2
3
4
5
6
7
8
9
10
11
// 获取时间戳
var date = new Date()
console.log(date.valueOf())
console.log(date.getTime())
var data1 = +new Date()
console.log(data1)
console.log(Date.now())
// 设置时间
var myDate=new Date();
myDate.setDate(myDate.getDate()+5);
console.log(myDate.toLocaleString());

数组对象

1
2
3
4
5
6
7
// 数组创建
var arr = new Array(2) // 长度为2,2个空元素;
var arr = new Array(1, 2) // 等价于[1, 2];
// 检测是否为数组
var arr = []
console.log(arr instanceof Array) // true,也可以检测是否为对象
Array.isArray(arr) // true
  • 数组添加删除数组元素的方法

  • 数组排序

注意sort排序,如果有多个数,则是按照第一位排序,需要回调函数;

  • 数组索引值

  • 数组转换成字符串

1
2
3
4
5
6
7
8
9
10
11
12
var colors = ['yellow', 'green', 'pink'];
var colors2 = colors.concat('black', ['blue', 'red']);
// slice(从开始位置,到结束位置不含结束位置)
var colors = ['yellow', 'green', 'pink', 'black', 'blue', 'red'];
var colors2 = colors.slice(1) // 索引值1到最后
var colors3 = colors.slice(1, 3) // 索引值1到3
var colors4 = colors.slice(-2, -1) // 倒数第2到第1
// splice(起始位置, 要删除的项数, 要插入的项)
var colors = ['yellow', 'green', 'pink'];
colors.splice(0, 1); //删除第一项
colors.splice(1, 0, 'blue', 'red'); //从位置1开始插入两项
colors.splice(1, 1 , 'black', 'orange') //插入两项,删除一项

字符串对象

1
2
3
4
5
6
7
8
// 基本包装类型(Number、String、Boolean)
// 把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。
// 1. 生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy');
// 2. 赋值给我们声明的字符变量
str = temp;
// 3. 销毁临时变量
temp = null;

字符串的不可变:

​ 当重新给 str 赋值的时候,常量’ abc ‘不会被修改,依然在内存中; 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变; 由于字符串的不可变,在大量拼接字符串的时候会有效率问题。

方法:

1
2
3
var str = '1231'
// 根据字符串的位置返回索引值;indexOf第二个参数可选,从第几个索引开始查找;
console.log(str.indexOf('1',[1]))
  • 根据字符串返回索引值

  • 根据位置返回字符串

  • 字符串方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var string = "hello world";
console.log(string.slice(3))// lo world 没有第二个参数,都是找到字符串结尾
console.log(string.substring(3))// lo world
console.log(string.substr(3))// lo world
console.log(string.slice(3, 7))// lo w 从索引位置3,找到索引位置7之前
console.log(string.substring(3, 7))// lo w
console.log(string.substr(3, 7))// lo worl 从索引位置3开始,往后找7个

console.log(string.slice(-3))// rld 将负数与字符串长度相加 11 + (-3) = 8
console.log(string.substring(-3)) //hello world 将负数转成0
console.log(string.substr(-3))// rld 将负数与字符串长度相加 11 + (-3) = 8

console.log(string.slice(3, -4))// lo w 从3,到倒数第4
console.log(string.substring(3, -4))// hel
//第二个参数是负数,直接转成0,相当于(3, 0)。但这个方法,会默认以小数开始,所以相当于(0, 3)
console.log(string.substr(3, -4))
// 第二个参数是负数,直接转成0, 相当于(3, 0)。返回0个字符串,即空字符串
  • 字符串replace替换
1
2
3
4
5
6
7
var str = 'andyandy'// 只会替换第一个字符,有多个后面的就不会;
console.log(str.replace('a','b'))// bndyandy
// 多个使用循环
while(str.indexOf('a')!== -1){
str = str.replace('a','b')
}
console.log(str)// bndybndy
  • 转换成大小写
1
2
3
var string = "Hello World";
console.log(string.toUpperCase())// HELLO WORLD
console.log(string.toLowerCase())// hello world
  • 判断数据类型
1
2
var timer = null
console.log(typeof timer)// object

复杂类型:变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中;