本文主要是介绍【coderwhy前端笔记 - 阶段二 JavaScript基础】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
js章节没有像前面四章(html+css)事无巨细的记录(暂未美化)
这里写目录标题
- 1 编写事项
- 1.1 编写方式
- 1.2 交互方式
- 1.3 注释
- 1.4 代码色块对齐
- 2 变量
- 2.1 命名规则
- 2.2 两个变量数字交换
- 2.3 声明
- 2.4 数组
- 3 数据
- 3.1 类型
- (1)Number 数字
- (2)String 字符串
- (3)Boolean 布尔
- (4)Undefined (已声明未赋值)(未定义)
- (5)Object 与 null
- 3.2 转换
- (1)转为string
- (2)转换Number
- (3)转为Boolean
- (4)直接赋值
- 3.3 运算
- (1)赋值运算
- (2)原地修改
- (3)++ - -
- (4)> < == ===
- 3 判断(分支)语句
- 3.1 if else
- 3.2 Switch
- 3.3 one ? two : three 三元运算
- 4 逻辑运算符 && || !
- 4.1 或 ||
- 4.2 且 &&
- 4.3 非 !
- 5 循环语句
- 5.1 while 检查 >> 迭代
- 5.2 do..while 迭代 >> 检查
- 5.3 for
- 5.4 循环控制
- 6 JavaScript函数
- 6.1 foo bar baz
- 6.2 函数使用步骤
- 6.3 形参 实参
- 6.4 返回值 return
- (1)无返回值 ()
- (2)执行完 return 退出函数
- (3)成功返回值
- (4)案例
- 6.5 arguments 存放所有传入的参数
- 6.6 函数中调用函数
- (1)递归
- (❤)递归的方式计算幂
- (❤)斐波那契
- 6.6 局部变量 外部变量
- 6.7 函数声明 与 函数表达式 区别
- 6.8 头等公民
- 6.9 回调函数
- 6.10 立即执行函数
- 7 面向对象
- 7.1 对象的基本使用
- 7.2 创建对象
- 7.3 操作对象
- (1)定义对象
- (2)访问对象
- (3)修改对象
- (4)添加对象
- (5)删除对象
- 7.4 方括号 []
- 7.5 遍历对象
- 7.6 栈内存 与 堆内存
- 7.7 值类型和引用类型
- 7.8 this
- 7.9 类和对象
- (1)痛点 >> 重复代码
- (2)工厂函数
- (3)构造函数 ⭐
- (❤)使用习惯
- (4)类方法
- 7.10 全局对象 window
- 8 常见内置类
- 8.1 包装类型
- (1)原始类型的包装类
- 8.2 数字类型 Number
- (1)toString(base) 转字符串
- (2)toFixed(digits) 格式化数字
- (3)Number.parseInt(变量名) 解析成整数
- (4)Number. parseFloat(string) 解析成浮点数
- 8.3 数学对象 Math
- (1)取整
- (2)随机数 Math.random() [0, 1)
- 8.4 字符串类型 String
- (1)使用
- (2)修改
- (3)查找
- (4)开头 结尾
- (5)替换
- (6)获取子字符串
- (7)concat 拼接 trim 删空格 split 切割 join 串联
- 8.5 数组 Array
- (1)创建
- (2)基本操作(增删改查)
- (3)增加和删除 ⭐splice
- (4)length属性
- (5)遍历
- (6)slice 截取 cancat 拼接 join 串联
- (7)查找 indexOf find
- (8)排序 sort reverse
- 8.6 Date
- (1)获取时间
- (2)获取时间戳
- (3)Date.parse
- (4)日期格式化
- 9 DOM
- 9.1 理解
- 9.2 DOM元素之间的关系
- (1)类
- (2)继承
- 9.4 获取DOM元素
- (1)对象
- (2)节点 与 元素
- (❤)节点
- (❤)元素
- (4)表格
- (5)元素( ID CSS 等 )
- 9.5 DOM节点的type、tag、content
- 9.6 DOM节点的attributes、properies 属性
- (1)元素的 attribute 属性
- (2)attribute 属性 的分类
- (3)attribute 属性 的操作
- (4)元素的 properies 属性
- (5)data- 自定义属性 (HTML5)
- 9.7 JavaScript 动态修改样式
- (1)已有样式,添加class
- (2)动态的修改style属性
- (3)dataset 使用
- 9.8 元素的常见操作
- (1)创建:createElement 插入
- (2)移除:remove 复制:cloneNode
- (3)案例
- (❤)prompt 动态列表
- (❤)动态显示时间
- 9.9 的大小、滚动、坐标
- (1)DOM元素
- (2)window
- 10 事件监听 略
- 11 DOM 实战 略
- 12 BOM 操作 略
- 90 document 语句
- 92 随手记函数
- 1、prompt 输入值
- 2、语法糖
- 3 debug
- 100 代码规范
1 编写事项
1.1 编写方式
<script src="xx.js"></script>
,不需要写type="text/javascript"
,因为默认就是这个类型
<script src="xx.js">alert("哈哈")</script>
引入js文件时,中间写的代码不生效
注意编写顺序,从上至下执行,一般将js文件放在</body
>上面
严格区分大小写
1.2 交互方式
// 1.交互方式一: alert函数
alert("Hello World");// 2.交互方式二: console.log函数, 将内容输出到控制台中(console)
// 使用最多的交互方式
console.log("Hello Coderwhy");// 3.交互方式三: document.write()
document.write("Hello Kobe");// 4.交互方式四: prompt函数, 作用获取用户输入的内容
var result = prompt("请输入你的名字: ");
alert("您刚才输入的内容是:" + result);
快速console.log方法
方式一:输入log
,回车
方式二:安装插件react
,输入clg
,回车
1.3 注释
// 1.单行注释// 2.多行注释/* 我是一行注释我是另外一行注释*/// 3.文档注释/*** 和某人打招呼* @param {string} name 姓名* @param {number} age 年龄*/function sayHello(name, age) {}sayHello()
1.4 代码色块对齐
代码编辑器 vscode 中打开 settings.json
加上👇
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs":"active"
2 变量
2.1 命名规则
首字母:字母 _
$
其他字母:字母 _
$
数字
不能使用 关键字和保留字
2.2 两个变量数字交换
方法一:借助第三个变量
var num1 = 10, num2 = 20, temp
temp = num1 // temp = 10
num1 = num2 // num1 = 20
num2 = temp // num2 = 10
方法二:不借助第三方
var num1 = 10, num2 = 20,
num1 = num1 + num2 // num1 = 30
num2 = num1 - num2 // num2 = 30 - 20 = 10
num1 = num1 - num2 // num1 = 30 - 10 = 20
2.3 声明
1、未声明(var pyy
) >> 直接使用 console.log(pyy)
>> 报错
console.log(name) // 未声明name时,默认为隐藏属性window.name,值为空// 若定义了var name = "pyy" ,则name为变量的值
2、已声明(var pyy
) >> 未赋值 >> undefined
3、建议声明(var pyy
) >> 无特定值 >> 赋值为null
2.4 数组
var names = ["abc", "cba", "nba", "mba", "bba", "aaa", "bbb"]
3 数据
3.1 类型
8种数据类型(7种原始类型和1种复杂类型)
Number
、String
、Boolean
、Undefined
、Null
、Object
、BigInt
(后续了解)、Symbol
(后续了解)
typeof返回的字符串有:
undefined
表示值未定义(未赋值)、boolean
表示值为布尔值、string
表示值为字符串、number
表示值为数值、object
表示值为对象(而不是函数)或null、function
表示值为函数、symbol
表示值为符号
内置类:Number String Boolean Symbol BigInt Math Array Date
(1)Number 数字
表示整数和浮点数:18 和 1.88,可做加减乘除运算。
特殊数值:
infinity
正无穷、(包括 1/0);
NaN
计算错误值,字符串 与 数字运算
十进制 var num1 = 111;
十六进制 var num2 = 0x111;
八进制 var num3 = 0o111;
二进制 var num4 = 0b111;
最小正数值:Number.MIN_VALUE,这个值为:5e-324,小于这个的数字会被转化为0
最大正数值:Number.MAX_VALUE,这个值为:1.7976931348623157e+308
isNaN:判断是不是一个数字,是true,否false
(2)String 字符串
字符串的三种包含方式""
、''
、``
。
""
、''
无区别
``
ES6新增语法,可在里面增加变量和表达式。(推荐)
var message3 = `Hello World, ${name}, ${2 + 3}`
特殊功能的字符可以通过转义字符的形式放入字符串\'
、\"
、\\
反斜杠、\t
制表符、\n
换行符
拼接:var str3 = str1 + str2
获取长度:console.log(str1.length)
(3)Boolean 布尔
true是1,false是0
(4)Undefined (已声明未赋值)(未定义)
已声明(var pyy
),未赋值,默认为undefined
注意:定义变量时就初始化(var pyy = null
),不要将一个变量赋值为undefined
(5)Object 与 null
object 为对象,用于合并多个变量
var info = {name: "a",age: 1,height: 1
}
打印某一个
console.log(info.name)
初始化值
- 已经知道设置为什么类型时
- 数字类型 👉 0,如: var age = 0
- 字符串类型 👉
""
,(空字符串) - 布尔类型 👉 false
(设置 0
、""
、false
,作为判断条件都会默认为 false)
- 没想好设置为什么类型
{}
,如:var pyy = {},if(pyy)
>>true
,不建议初始化为{}
null
,如:var pyy = null ,if(pyy)
>>false
,推荐!
null 表示对象为空,用于未知的值,不确定对象时,可以赋值null
注意:null 的 typeof 为 object
var address = null
console.log(typeof address) // Object
3.2 转换
console.log(typeof a)
打印 a 的类型
(1)转为string
隐式(⭐):
string + 任何类型 = string
如:var num1 = 11; var numStr = num1 + "";
,numStr 自动转为string
显示:
调用string()函数,如string(num1)
调用toString()方法
(2)转换Number
算数运算会将其他类型转换为数字,(少用)
比如 "6" / "2"
,但 number + string = string
调用Number()
函数,(⭐)
string案例:
console.log(Number("abc123")) // NaN
console.log(Number(" 123 ")) // 123
console.log(Number("")) // 0
(3)转为Boolean
显示转换:调用Boolean(value)
隐式转换:
(4)直接赋值
var a = "aaa" // 此时为字符串类型
a = 1 // 此时为数字类型
3.3 运算
(1)赋值运算
幂运算
console.log(Math.pow(2, 4)) 等于 console.log(2 ** 4)
链式赋值:从右到左进行计算
var a, b, c;
a = b = c= 2 + 2;
console.log(a, b, c) // 4 4 4
求奇偶
关键代码num % 2 == 0
, yes >> 偶数
no >> 奇数
var num = 120if (num % 2 !== 0) { // 奇数console.log(`${num} 是一个奇数`)}else{console.log(`${num} 是一个偶数`)}
(2)原地修改
(3)++ - -
方式一:a += 1
>> a = a + 1
方式二:i++
加 1,i--
减 1,只能用于变量( i++ ✔) ( 5++❌ )
后置形式:counter++,(先计算,计算结束,再自增)
前置形式:++counter,(先自增,再计算,计算结束)
独立使用 counter++
和 ++counter
无区别
var num1 = 5 !假设每行运算前都给 num 赋值 5
var result1 = 100 + num1++ // 先用原值参与计算,再自增// result: 105 num1: 6
var result2 = 100 + ++num1 // 先用原值自增,再计算// result: 106 num1: 6
var result3 = num1++ + 100 // 先用原值计算,再自增// result:105 num1: 6
var result3 = ++num1 + 100 // 先用原值自增,再计算// result:106 num1: 6
运算,参考优先级表格
var num = 5; var result = 2 + 3 * ++num
先自增,++num = 6
再乘法,3 * 6 = 18
后加法,2 + 18 = 20
(4)> < == ===
大于 >
,小于<
,==
相等性检查(两边值会先被转化为数字,此为隐式转换),===
比较类型和内容(不做任何类型转换)
3 判断(分支)语句
3.1 if else
if() {}
的()为计算的表达式,结果为 Boolean 值
假值(falsy):0
、空字符串 ""
、null
、undefined
、NaN
都会被转换成false
真值(truthy):其他值被转成true
if(){}
只有一行时,可以省略{}
,如 if (num1 > 5) num2 -= 8
3.2 Switch
switch (表达式/变量) {case 常量1:console.log("常量1")breakdefault:console.log("没有找到")break
}
不加 break 会默认穿透,直至switch结束。
合并case写法:
switch (表达式/变量) {case 常量1: case 常量2: case 常量3:console.log("heihei")breakdefault:console.log("没有找到")break
}
3.3 one ? two : three 三元运算
因为有三个操作数
var result = condition ? value1 : value2条件 为真时 为假时
如:a b 比大小
var a = 10, b = 20
var result = a > b ? yes : no
console.log(a,b,result)
如:让用户输入一个年龄, 判断是否成年人
var age = prompt("请输入您的年龄:")
age = Number(age)
var message = age >= 18 ? "成年人": "未成年人"
alert(message)
4 逻辑运算符 && || !
与&&
>> 短路与
或||
>> 短路或
4.1 或 ||
【❤】
运算元1 || 运算元2 || 运算元3
运算元1:var name = "pyy"
// true,到此截至
运算元2。。。。。 不看
运算元3。。。。。 不看
【❤】
有 var message = info
,当使用 console.log(message)
,但我们不清楚 info
是否有内容时
可以将 var message = info
改成 var message = info || "我是默认值"
【❤】
将运算元暂时转为boolean值进行判断,最后返回的仍是原始值
var info = "abc"
var obj = {name: "pyy"}
var message = info || obj || "我是默认值"对(true)
得:var message = info,此时 message = info = "abc"
4.2 且 &&
【❤】
运算元1 || 运算元2 || 运算元3
运算元1:var name = ""
// false,到此截至
运算元2。。。。。 不看
运算元3。。。。。 不看
【❤】找找有没有obj,
4.3 非 !
!
反转
!!
反转再反转,就是变为原有值的布尔类型,案例看我
5 循环语句
也称为遍历或迭代
5.1 while 检查 >> 迭代
成立 >> 执行代码块
不成立 >> 跳出代码块
while(循环条件){ 循环代码块 }
如果条件一直成立 >> 死循环 (需要避免)
5.2 do…while 迭代 >> 检查
不管条件成不成立,都会先执行一次do的循环代码块
do { 循环代码块 } while(条件)
更倾向于使用while
5.3 for
for(begin;condition;step){ 循环代码块 }
for(let i = 0; i < 3; i++){ alear("hh") }
5.4 循环控制
break 跳出循环,结束
var names = ["abc", "cba", "nba", "mba", "bba", "aaa", "bbb"]
for (var i = 0; i < names.length; i++) {if (names[i] === "nba") {break // 直接结束到for外面}console.log(names[i])
} // abc cba
continue 跳过本次循环,执行下一个循环体
for (var i = 0; i < names.length; i++) {if (names[i] === "nba" || names[i] === "cba") { // 遇到nba 或者 cba 跳过本次循环continue}console.log(names[i])
}
6 JavaScript函数
6.1 foo bar baz
本身没有特别得用途和意义,常被称之为“伪变量”,一般用于不知道起什么名字时使用
foo >> var foo = "aaa"
>> 做变量名
bar >> function bar() { }
>> 做函数名
baz >> var baz = { }
>> 做数组名
6.2 函数使用步骤
-
声明函数 —— 封装 独立的功能
function 函数名() { 函数封装的代码 }
-
调用函数 —— 享受 封装的成果
函数名()
6.3 形参 实参
形参:接收参数用的,作为变量使用
实参:把数据传递到函数内部
// 声明函数function myInfo(name,age) { // 形参,理解为变量console.log(`名字:${name},年龄:${age}`)}// 调用函数myInfo("pyy",45) // 实参,理解为具体内容
6.4 返回值 return
(1)无返回值 ()
情况一:未在函数内写return
function sayHello(name) {console.log(`Hi ${name}`) // 此处打印:Hi Kobe}var foo = sayHello("Kobe")console.log("foo:", foo) // 此处打印:foo:undefined
情况二:虽然写return
,但无返回值
function baz() {console.log("Hello Baz")returnconsole.log("Hello World")console.log("Hello Why")}baz()
(2)执行完 return 退出函数
执行到 return
时,函数立即停止执行,退出函数
function baz() {console.log("Hello Baz") // 此处打印:Hello Bazreturnconsole.log("Hello World")console.log("Hello Why")}baz()
(3)成功返回值
⭐成功返回值的条件:
- 声明函数中的
return
要有具体的值 - 调用该函数
有参数,返回参数值
function sum(text) {return text}var summ = sum("hhh")console.log("return值", summ) // 此处打印:return值 hh
无参数,返回字符串
function sum() {return "hh"}var summ = sum()console.log("return值", summ) // 此处打印:return值 hh
(4)案例
传入一个数字n, 计算1~n的数字和
function sumN(n) {// 1.加对n的判断if (n <= 0) {console.log(`您传入的${n}是有问题的`)return}// 2.真正对1~n的数字进行计算// 1~n的数字和// 1~5 1 2 3 4 5var total = 0for (var i = 1; i <= n; i++) {total += i}return total}var result1 = sumN(5)var result2 = sumN(10)console.log(`result1: ${result1}, result2: ${result2}`)var result3 = sumN(-10)console.log("result3:", result3)
6.5 arguments 存放所有传入的参数
arguments 函数存放所有调用者(步骤二)传入的参数。
步骤一:声明函数function foo(name,age) { 仅调用了前面两个,并命名为name和age// console.log(arguments[0]) // 此处打印:pyy// console.log(arguments[1]) // 此处打印:45// console.log(arguments[2]) // 此处打印:hhhconsole.log(argument) // 参数用的不一样,看个效果图}步骤二:调用函数foo("pyy",45,"hhh") arguments存放了`"pyy",45,"hhh"`
有返回值的方法
function sum() {var total = 0for (var i = 0; i < arguments.length; i++) {var num = arguments[i]total += num}return total}console.log(sum(10, 20))console.log(sum(10, 20, 30))console.log(sum(10, 20, 30, 40))
6.6 函数中调用函数
(1)递归
函数调用自己 >> 递归
必须要有结果,否则产生无限调用,造成报错
缺点: 性能是比较低(占用过多的栈内存)
优点: 写出来的代码非常简洁
(❤)递归的方式计算幂
递归的方式计算 23
function pow(x, n) { if(n === 1) return x return x * pow(x, n-1) }console.log(pow(2, 3))
实现思路:
xn = x * xn-1 >> pow(2,3) = 2 * pow(2,2)
理解为23 = 2 * 22,运算规则在pow()
里
运行步骤:
详细 👇
简约 👇
(❤)斐波那契
数列: 1 1 2 3 5 8 13 21 34 55 … x
位置: 1 2 3 4 5 6 7 8 9 10 … n
f(n) = f(n-1) + f(n-2)
等于前面两个数字的合
function fibonacci(n) {if (n === 1 || n === 2) return 1return fibonacci(n-1) + fibonacci(n-2)}
6.6 局部变量 外部变量
ES5前没有块级作用域,但 function 函数可以定义自己的作用域(有效范围)
函数a 内部有 函数b,a内定义的变量,b可以访问到
概念:
函数内部 >> 局部变量 >> 在函数内部定义的变量
函数外部 >> 外部变量 >> 在函数 内部 去 访问 函数之外的变量,访问的变量称之为外部变量
全局变量:
函数外声明的变量,在任何函数中都可见的,通过var声明的全局变量会在window对象上添加一个属性
访问顺序:优先访问自己函数中的变量,没有找到时,在外部中访问
6.7 函数声明 与 函数表达式 区别
函数声明:在主代码流中声明为单独的语句的函数。
在函数声明被定义之前,它就可以被调用(js准备运行脚本时,首先会寻找全局函数声明,并创建这些函数),👇
在该声明中,fuction foo() 为单独的语句,调用语句foo(),放在前或后都可以
foo() // 放这里可以function foo() {console.log("foo函数被执行了~")}foo() // 放这里也可以
函数表达式:在一个表达式中或另一个语法结构中创建的函数。
在代码执行到时才被创建,并且仅从那一刻起可用,👇
将调用函数bar() 放在上面会报错,bar is not a function
bar() // 报错var bar = function() {console.log("bar函数被执行了~")}bar() // 可以
6.8 头等公民
函数作为一等(头等)公民
作用:
- 函数可以被赋值给变量(函数表达式)👆
- 让函数在变量之间来回传递
var foo1 = function() {console.log("foo1函数被执行~")}var foo2 = foo1 // = 👆foo2() // 译为调用foo2()函数 -> 调用foo1()
- 函数可以作为另一个函数的参数
var foo1 = function() {console.log("foo1函数被执行~") // 1、打印一次 6、再次打印}function bar(fn) { // 3、bar()带入变量foo1代码console.log("fn:", fn) // 4、此时未执行fn()->foo1()函数,打印该函数代码fn() // 5、执行fn()->foo1()函数}bar(foo1) // 2、执行 bar()
- 函数作为另一个函数的返回值
function sayHello() {function hi() {console.log("hi kobe") // 4、执行打印}return hi // 2、结束!返回 hi()函数,此时 var fn = hi()}var fn = sayHello() // 1、运行sayHello函数fn() // 3、执行fn(),相当于执行hi()
- 将函数存储在另外一个数据结构中
var obj = {name: "why",eating: function() {console.log("eating")}}console.log(obj); // 1、{name: 'why', eating: ƒ}obj.eating() // 2、eating
function bar1() {console.log("bar1函数被执行~")}function bar2() {console.log("bar2函数被执行~") // 3、bar3函数被执行~}function bar3() {console.log("bar3函数被执行~")}// 事件总线的封装var fns = [bar1, bar2, bar3]console.log(fns); // 1、(3) [ƒ, ƒ, ƒ]fns[2]() // 2、调用bar2()
6.9 回调函数
概念:通过 fn 去调用 bar 函数的过程, 称之为函数的回调
function foo(fn) {fn() // 2、fn = bar。 fn() -> 执行参数bar()}function bar() {console.log("bar函数被执行了~") // 3、打印}foo(bar) // 1、bar作为参数传入foo()
案例:
function request(url, callback) {console.log("根据URL向服务器发送网络请求") // 2、打印console.log("需要花费比较长的时间拿到对应的结果") // 3、打印var list = ["javascript", "javascript学习", "JavaScript高级编程"] // 4、新增变量 list callback(list) // 5、此时callback 值为 handleResult 的代码,} // callback(list) -> handleResult(list)function handleResult(res) { // 1.5、此时函数 handleResult 作为参数传入函数request(),注意:此时未执行console.log("在handleResult中拿到结果:", res) // 6、handleResult(list)被执行,效果如图}request("url", handleResult) // 1、执行request(),传入参数:字符串"url"和 handleResult
省略 handleResult() 的写法
// 3.函数回调的案例重构function request(url, callback) {console.log("根据URL向服务器发送网络请求")console.log("需要花费比较长的时间拿到对应的结果")var list = ["javascript", "javascript学习", "JavaScript高级编程"]callback(list)}// 传入的函数是没有名字, 匿名函数request("url", function(res) {console.log("在handleResult中拿到结果:", res)})
6.10 立即执行函数
现在少用,了解一下
写法:(匿名函数)()
,立即执行匿名函数
(function() {})() // 执行的 () 放在外面,常用(function(fn) {}()) // 执行的 () 放在里面+function foo(){}() // 非主流写法,一般不会有人写(function() { console.log("立即执行函数被调用~")})()
错误写法👇,函数声明不能立即调用,函数表达式才可以
function foo(){}()
立即执行函数的参数和返回值:
var result = (function(name) { // 1、(匿名函数)(name),直接执行该匿名函数,参数name的值为"pyy"console.log("函数立刻被执行~", name) // 2、打印:函数立刻被执行~ pyyreturn "Hello World" // 3、函数停止,返回字符串"Hello World"。var result = "Hello World"})("pyy")console.log(result) //4、打印result:"Hello World"
应用:
- 防止全局变量的命名冲突
立即执行函数中定义的变量有自己的作用域
(function() {var message = "Hello World"console.log(message) // 可打印})()console.log(message) // 找不到,message is not defined
多人编写js,都恰好使用到 var message时,会造成混乱
当立即执行函数想要把某个变量返回出去时,👇,别看 不用这个了
var xmModule = (function() {var xmModule = {}var message = "Hello XiaoMing"console.log(message)console.log(message.length)xmModule.message = messagereturn xmModule
})()
- 案例:监听按钮
条件:
知识点:
仅拿到按钮1:👇
var btnEl = document.querySelector(".btn") // 仅拿到按钮1console.log(btnEl) // 打印 “<button class="btn">按钮1</button>”btnEl.onclick = function() {console.log("点击了按钮1") // 点击后打印}
获取所有的按钮监听点击:👇
(未使用立即执行函数 👇)
var btnEls = document.querySelectorAll(".btn")console.log(btnEls); // 获取到四个按钮for (let i = 0; i < btnEls.length; i++) { // i<4,此处只能用let,使块级作用域生效,用 var 会导致执行btn.onclick时i一直为4var btn = btnEls[i];console.log(btn); // i = 0 时,打印“<button class="btn">按钮1</button>”btn.onclick = function() { // i = 0 时,btn = btnEls[0],btn.onclick = btnEls[0].onclickconsole.log(`按钮${i+1}发生了点击`) // i = 0 时,打印:按钮1发生了点击console.log(btn); // i = 0 时,打印“<button class="btn">按钮1</button>”}}
(使用立即执行函数 👇)
var btnEls = document.querySelectorAll(".btn") // 获取到四个按钮for (var i = 0; i < btnEls.length; i++) {var btn = btnEls[i]; // i = 0 时,btn = <button class="btn">按钮1</button>(function(m) { // (匿名函数)(m),直接执行该匿名函数,参数m的值为"i"btn.onclick = function() {console.log(`按钮${m+1}发生了点击`) // 传入参数 i 后,这里相当于按钮${i+1}发生了点击}})(i)}console.log(i) // for已经执行完毕,i = 4
7 面向对象
7.1 对象的基本使用
var person = {// key: valuename: "ppy"age: 88run: function() {console.log("hh")}}
函数 vs 方法
函数function foo() {}方法 // (将一个函数放在对象里,作为对象的一个属性)var person = {name: function() {}}
key: value
的 key 大多数情况下可以省略引号。"name": "pyy"
>> name: pyy
当 key 存在空格,如 my friend
就必须加上引号 >> "my friend"
7.2 创建对象
- 对象字面量,
var obj1 = { }
- Object 构造函数
var obj2 = new Object()obj2.name = "kobe"
- new 其他类()
function Person() {}var obj3 = new Person()
7.3 操作对象
(1)定义对象
var info = {name: "why",age: 18,friend: {name: "kobe",age: 30},running: function() {console.log("running~")}}
(该代码作为《访问对象》《修改对象》《添加对象》《删除对象》的前提)
(2)访问对象
(3)修改对象
info.age = 25 // 1info.running = function() { // 2console.log("I am running~") // 6.打印:I am running~}console.log(info.age) // 4.打印:25info.running() // 5.执行
(4)添加对象
info.height = 1.88info.studying = function() {console.log("I am studying~")}console.log(info)
(5)删除对象
delete
未删除时:
删除代码:
delete info.age
删除后:
7.4 方括号 []
info.good friend = "hh"
>> js无法理解
info["good friend"] = "hh"
>> 可以理解
使用案例
var obj = {name: "why","my friend": "kobe","eating something": function() {console.log("eating~")}}console.log(obj["my friend"])console.log(obj.name)console.log(obj["name"]) // 跟上面一样// obj["eating something"]()var eatKey = "eating something"obj[eatKey]()
结果:
.
和 []
区别
点方法 .
:后面接的是一个属性名称
中括号 []
:中括号里可以是字符串、数字、变量、属性名
7.5 遍历对象
Object.keys()
方法会返回一个由一个给定对象的自身可枚举属性组成的数组;
var info = {name: "why",age: 18,height: 1.88}console.log(Object.keys(info)) // 打印的是key名称,['name', 'age', 'height']// 对对象进行遍历// 1.普通for循环var infoKeys = Object.keys(info)for (var i = 0; i < infoKeys.length; i++) {var key = infoKeys[i]var value = info[key]console.log(`key: ${key}, value: ${value}`) // key: name, value: why} // key: age, value: 18// key: height, value: 1.88// 2.for..in..: 遍历对象for (var key in info) {console.log(key); // key是打印对象的key名称,info[key]是打印值var value = info[key] // 打印值console.log(`key: ${key}, value: ${value}`)}// for..of..: 默认是不能遍历对象
7.6 栈内存 与 堆内存
案例一:
案例二:
function foo(a) { // 3、a = 100a = 200 // 4、a = 200,等于一个新值,对原来的num没有影响}var num = 100 // 1、num = 100foo(num) // 2、foo(num),传入100console.log(num) // 5、打印:100
同理:
案例三 👇
function foo(a) {a = {name: "why" // 未传出值}}var obj = {name: "obj" }console.log(foo(obj)) // 打印:underfundedconsole.log(obj) // 打印:{ name: "obj" }
原理图
案例四
var m = {}
var n = {}
console.log(m === n) // false
m、n 虽然同为空对象,但指向不同的堆内存地址,所以不相等
7.7 值类型和引用类型
值类型
- 原始类型的保存方式:在变量中保存的是值本身
- 所以原始类型也被称为值类型
引用类型
- 对象类型的保存方式:在变量中保存的是对象的 “引用”
- 所以对象类型也被称为引用类型
7.8 this
this代表的是当前调用对象
全局环境 >> this 指向 window
对象调用 >> this 指向 调用对象
情况一:如果普通的函数被默认调用, 那么this指向的就是window
情况二: 如果函数它是被某一个对象来引用并且调用它, 那么this会指向这个对象
情况三:变量
情况四:对象与声明函数
7.9 类和对象
(1)痛点 >> 重复代码
解决痛点:重复代码
创建一个班45个学生(对象)
(2)工厂函数
解决方案 ——> 工厂函数( 工厂生产student对象) ——> 一种设计模式
打印时,对象的类型都是Object
(3)构造函数 ⭐
构造函数也称之为构造器(constructor)通常是我们在创建对象时会调用的函数;
JavaScript已经默认提供给了我们可以更加符合JavaScript思维方式(面向对象的思维方式)的一种创建对象的规则。new
// JavaScript已经默认提供给了我们可以更加符合JavaScript思维方式(面向对象的思维方式)的一种创建对象的规则// 在函数中的this一般指向某一个对象/*如果一个函数被new操作符调用1.创建出来一个新的空对象2.让this指向这个空对象3.执行函数体的代码块4.如果没有明确的返回一个非空对象, 那么this指向的对象会自动返回*/function coder(name, age, height) { // 3.执行函数体的代码块this.name = name this.age = agethis.height = heightthis.running = function() {console.log("running~")}// return this 省略return // 如果没有明确的返回一个非空对象, 那么this指向的对象会自动返回}// 在函数调用的前面加 new 关键字(操作符)var stu1 = new coder("why", 18, 1.88) // 1.创建出来一个新的空对象 2.让this指向这个空对象var stu2 = new coder("kobe", 30, 1.98)console.log(stu1, stu2)
类的表现形式就是构造函数
- 构造函数也时普通函数
- 普通函数被使用
new
操作符来调用,那这个函数就称之为一个构造函数
一个函数被使用 new
操作符调用了,会执行以下操作:
- 在内存中创建一个新对象(空对象)
- 这个对象内部的[[prototype]]属性会被赋值为该构造 函数的prototype属性
- 构造函数内部的this,会指向创建出来的新对象
- 执行函数的内部代码(函数体代码)
- 如果构造函数没有明确的返回一个非空对象, 那么this指向的对象会自动返回
(❤)使用习惯
(4)类方法
构造函数上(类上面)添加的函数, 称之为类方法
Dog.running = function() {}
Dog.running()
7.10 全局对象 window
省略,代码 07_JavaScript对象的使用\15_额外补充-全局对象window.html
8 常见内置类
8.1 包装类型
(1)原始类型的包装类
① var name = “pyy”
② console.log(name.length)
本来原始类型就是简单的值(①),不能调用属性和方法(② ×),但是JavaScript为使其可以获取属性和调用方法,对其封装了对应的包装类型(② ✔)
常见的包装类型有:String、Number、Boolean、Symbol、BigInt类型
8.2 数字类型 Number
本身存在一个number的构造函数
Number构造函数 -> Window.Number
// 类属性// Number中本身是有自己的属性console.log(Number.MAX_VALUE) // 最大值console.log(Number.MIN_VALUE) // 最小值// integer: 整数console.log(Number.MAX_SAFE_INTEGER) // 最大整数console.log(Number.MIN_SAFE_INTEGER) // 最小整数
方法补充
(1)toString(base) 转字符串
var num = 1000console.log(num.toString(), typeof num.toString()) // 转字符串类型console.log(num.toString(2)) // 转二进制console.log(num.toString(8)) // 转八进制console.log(num.toString(16)) // 转十六进制
(2)toFixed(digits) 格式化数字
保留digits位小数(0~20)
var pi = 3.1415926console.log(pi.toFixed(3))
(3)Number.parseInt(变量名) 解析成整数
var num1 = "123.521"console.log(Number.parseInt(num1))
(4)Number. parseFloat(string) 解析成浮点数
浮点数(有小数)
var num1 = "123.521"console.log(Number.parseFloat(num1))
8.3 数学对象 Math
(1)取整
取整数,去掉小数点
(1)Math.round() 按“周围”理解,四舍五入
(2)Math.floor() 按“地板”理解,向下取舍
(2)随机数 Math.random() [0, 1)
生成一个0~99的随机数
var randomNum = Math.floor(Math.random() * 100)
Math.random() >> 生成 [0, 1) >> 如:0.5471947852060866
Math.random() * 100 >> 如:54.71947852060866
Math.floor(Math.random() * 100) >> 如:55.
8.4 字符串类型 String
(1)使用
获取长度 .length
访问某个位置的字符
变量名[4]
>> 访问第五个字符(从0开始) >> 超出时为undefined
变量名.charAt(4)
>> 一个方法:访问第五个字符 >> 超出时为空
遍历
for普通遍历: for (var i = 0; i < message.length; i++) { }
for…of 的遍历:for (var char of message) { }
(只有迭代器支持 for…of 遍历,目前可迭代对象:字符串、数组)
(2)修改
字符串在定义后是不可以修改的
var message = "Hello World"message[2] = "x" // 无任何反应,不支持修改字符串message = "aaa" // 不能算严格意义上的修改字符串// 此处为将一个新的字符串赋值给message
变大写和变小写
// String两个方法:(重要)toUpperCase: 将所有的字符变成大写toLowerCase: 将所有的字符变成小写var message1 = message.toUpperCase() // 生成新字符串(message的大写)赋值给新的变量message = message.toUpperCase() // 生成新字符串(message的大写)赋值给message
(3)查找
方法一:
判断一个字符串中是否存在另外一个字符串:
变量名.indexOf("pyy")
- 存在,返回所在的索引位置(第一个字符)
- 不存在,返回
-1
var message = "my name is why."var name = "why"var index = message.indexOf(name) // 11if (message.indexOf(name) !== -1) {console.log("message中包含name")} else {console.log("message不包含name")}
方法二:
判断包含关系,message.includes(name)
>> message内是否包含name(var name = “pyy”)
- 包含,true
- 不包含,false
(4)开头 结尾
是否以xxx开头,message.startsWith("my")
>> message是否以 “my” 开头
是否以xxx结尾,message.endsWith("my")
>> message是否以 “my” 结尾
(5)替换
替换字符串,message.replace("why", "kobe")
>> 找到 why,替换成kobe
var message = "my name is why."var name = "why"var newName = "kobe"var newMessage = message.replace("why", function() {return newName.toUpperCase() // 返回newName大写}) // newMessage = my name is KOBE.
(6)获取子字符串
常用slice,一般不用substr
var message = "Hello World"// 获取子字符串console.log(message.slice(3, 7)) // 获取第 3 4 5 6 个字符console.log(message.slice(3, -1)) // 获取第 3 个 至 倒数减 1 个console.log(message.slice(3)) // 获取第 3 个 至 最后// substrconsole.log(message.substr(3, 7)) // 获取第 3 个开始,打印 7 个字符
(7)concat 拼接 trim 删空格 split 切割 join 串联
8.5 数组 Array
(1)创建
创建数组
索引访问数组中某元素,0开始编号
console.log(names[0]) // 第一个元素console.log(names[names.length-1]) // 最后一个元素
(2)基本操作(增删改查)
(3)增加和删除 ⭐splice
操作头部:
names.unshift("a") 在头部添加元素names.shift() 在头部删除一个元素
操作尾部:
names.push("a", "b") 在尾部添加元素names.pop() 从尾部删除一个元素
任意位置添加、删除、替换:
splice:从 index 1 开始删除 2 个
names.splice(1, 2)
⭐ splice!可以添加、删除、替换
names.splice(3,1,"pyy","pyyyy") // 在位置3,删除1个,插入2个
-
array.splice(start, deleteCount, [item1, ....])
-
start:从start位置开始,(操作位置start),(0,1,2,3…)
-
deleteCount:删除几个(0或负表示不删除)
-
[item1, …]:从start位置后面,添加的元素
(4)length属性
(5)遍历
(6)slice 截取 cancat 拼接 join 串联
slice 截取数组,译为显示哪个
显示第2 第3个 (从0开始,到end-1个,不包含end)
names.slice(2,4)
区别:
slice方法: 不会修改原数组
splice方法: splice修改原有的数组
concat 拼接
var newNames2 = names1.concat(names2, names3)
join 将一个数组连接起来形成字符串
console.log(names.join("-"))
(7)查找 indexOf find
.indexOf
方法:查找某个元素的索引 >> 图1.find
和findIndex
直接查找元素或者元素的索引 >> 图2.includes
方法:判断数组是否包含某个元素
解释find原理
var stu = students.find(function(item) { // find 会查找 students 的对象,有4个对象,则 find 4次// 如第一次:item = students[0],即 { id: 100, name: "why", age: 18 }if (item.id === 101) return true // 结束!找到了})console.log(stu)
⭐快捷的箭头函数写法
var stu = students.find(item => item.id === 101)
console.log(stu)
高阶函数:函数的参数是函数
(8)排序 sort reverse
8.6 Date
(1)获取时间
打印结果:2022/11/22 6:17:54
var year = date.getFullYear()var month = date.getMonth() + 1var day = date.getDate()var hour = date.getHours()var minute = date.getMinutes()var second = date.getSeconds()console.log(year, month, day, hour, minute, second)console.log(`${year}/${month}/${day} ${hour}:${minute}:${second}`)
(2)获取时间戳
方式一:new Date().getTime()
将date对象转化为时间戳 ⭐
方式二:new Date().valueOf()
将date对象转化为时间戳 ⭐
方式三:+new Date()
不用看
方式四:Date.now()
获取当前时间戳
测试代码性能
(3)Date.parse
将字符串时间转成时间戳
var timeString = "03/23/2033"// 1.方式一:var date = new Date(timeString)var timestamp = date.getTime()// 2.方式二:var timestamp = Date.parse(timeString)console.log(timestamp)
(4)日期格式化
后面的写更好
9 DOM
ppt:10_JavaScript的DOM操作(一)
9.1 理解
DOM
- 文档对象模型,将页面所有的内容表示为可以修改的对象 >> Document
- DOM是浏览器文档和JavaScript语法之间的桥梁
- 通过js来操作文档的某个元素
BOM:浏览器对象模型,有浏览器提供的用于处理文档之外的所有内容的其他对象,如 navigator、location、history
9.2 DOM元素之间的关系
(1)类
省略重复代码
父类 Person,Student 和 Teacher 是 Person 的子类
(2)继承
9.4 获取DOM元素
(1)对象
(2)节点 与 元素
(❤)节点
如果我们获取到一个节点(Node)后,可以根据这个节点去获取其他的节点,我们称之为节点之间的导航。
节点包括:注释 文本 等
(❤)元素
常用
如果我们获取到一个元素(Element)后,可以根据这个元素去获取其他的元素,我们称之为元素之间的导航。
元素包括:div、ul、li
(4)表格
案例
// 获取body中第一个元素 已知为tablevar tableEl = document.body.firstElementChild// 通过table元素获取内部的后代元素console.log("body 的第一个元素",tableEl);console.log("表格的tHead", tableEl.tHead)console.log("表格的tBodies", tableEl.tBodies);console.log("表格的tFoot", tableEl.tFoot);console.log("表格的rows", tableEl.rows)// 拿到一行元素var rowEl = tableEl.rows[2] // 第三行console.log(rowEl.cells[0]) // 第一个console.log(rowEl.sectionRowIndex)console.log(rowEl.rowIndex)// 1.获取1-1var row1El = tableEl.rows[0]var cell1El = row1El.cells[0]console.log(cell1El)// 2.获取2-2var row2El = tableEl.rows[1]var cell2El = row1El.cells[1]// for循环for (var i = 0; i < tableEl.rows.length; i++) {var rowEl = tableEl.rows[i]var cellEl = rowEl.cells[i]// 设置样式cellEl.style.backgroundColor = "red"cellEl.style.color = "white"}
(5)元素( ID CSS 等 )
querySelector ⭐ 常用
querySelectorAll
getElementByld
getElementsByName
getElementsByTagName
getElementsByClassName
9.5 DOM节点的type、tag、content
节点的属性
nodeType 节点的类型:1 - 元素,2 - 属性,3 - 文本,8 - 注释
nodeName:获取node节点的名字
tagName:获取元素的标签名词
innerHTML: 对应的html元素也会获取
textContent: 只会获取文本内容
nodeValue / data:用于获取非元素节点的文本内容
boxEl.hidden = true
,隐藏
9.6 DOM节点的attributes、properies 属性
元素 中的属性称之为 attribute
对象 中的属性称之为 property
标准的attribute在对应的对象模型中都有对应的property
(1)元素的 attribute 属性
(2)attribute 属性 的分类
标准的attribute: 某些attribute属性是标准的,比如id、class、href、type、value等;非标准的attribute: 某些attribute属性是自定义的,比如abc、age、height等;
(3)attribute 属性 的操作
elem.hasAttribute(name) >> 检查特性是否存在
elem.getAttribute(name) >> 获取这个特性值
elem.setAttribute(name, value) >> 设置这个特性值
elem.removeAttribute(name) >> 移除这个特性
attributes >> attr对象的集合,具有name、value属性
特征:
- 名字是大小写不敏感的、
- 值总是字符串类型的
(4)元素的 properies 属性
对于标准的attribute,会在DOM对象上创建与其对应的property属性
(5)data- 自定义属性 (HTML5)
<div class="pyy" data-name="box" data-age="45"></div>
9.7 JavaScript 动态修改样式
(1)已有样式,添加class
选择一: 在CSS中编写好对应的样式,动态的添加class
className方法
boxEl.className = "abc"
>> 添加一个类
注意:boxEl.className = "abc"
>> 赋值会替换整个class,添加类建议用👇add()
classList 方法
boxEl.classList.add (class)
>> 添加一个类
boxEl.classList.remove(class)
>> 移除类
boxEl.classList.toggle(class)
>> 如果类不存在就添加类,存在就移除它。
boxEl.classList.contains(class)
>> 检查给定类,返回 true/false。
classList是可迭代对象,可以通过for of进行遍历。
(只有迭代器支持 for…of 遍历,目前可迭代对象:字符串、数组)
(2)动态的修改style属性
选择二:动态的修改style属性
可通过getComputedStyle
全局函数来读取样式
(3)dataset 使用
var boxEl = document.querySelector(".box")// 小程序开发中使用console.log(boxEl.dataset.age)console.log(boxEl.dataset.height)
9.8 元素的常见操作
(1)创建:createElement 插入
创建一个DOM对象,并插入
// 2.真实创建一个DOM对象var h2El = document.createElement("h2") // 创建一个<h2></h2>h2El.className = "title" // 添加class="title"h2El.classList.add("active") // 添加class="active"h2El.textContent = "我是标题" // 添加文字// 将元素插入boxElboxEl.append(h2El) // 在boxEl 的末尾插入boxEl.prepend(h2El) // 在boxEl 的开头boxEl.after(h2El) // 在boxEl 的后面插入boxEl.before(h2El) // 在boxEl 的前面boxEl.replaceWith(h2El, "abc") // 替换boxEl 为 h2El 和 abc
(2)移除:remove 复制:cloneNode
// 1.获取元素var boxEl = document.querySelector(".box") // 一个divvar removeBtnEl = document.querySelector(".remove-btn") // 移除按钮var cloneBtnEl = document.querySelector(".clone-btn") // 复制按钮// 2.监听removeBtn的点击removeBtnEl.onclick = function() {boxEl.remove() // 移除div}// 3.复制boxvar counter = 0cloneBtnEl.onclick = function() {var newNode = boxEl.cloneNode(true) // 复制boxEl的内容。true -> 深度复制newNode.children[0].textContent = "我是标题" + counter // "克隆人box"的第1个子元素文字替换为:// boxEl.after(newNode)document.body.append(newNode) // 在body的末尾处插入counter++}
(3)案例
(❤)prompt 动态列表
<h1>动态创建列表</h1><ul class="list"></ul><script>var ulEl = document.querySelector(".list")var isFlag = truewhile (isFlag) {var message = prompt("请输入信息:")if (!message) { // 没有输入内容isFlag = false} else {var liEl = document.createElement("li")liEl.textContent = messageulEl.append(liEl)}}</script>
(❤)动态显示时间
// 封装了工具函数:除了年,保持两位数function padLeft(content, count, padStr) {count = count || 2 // 没有count值,则为 2padStr = padStr || "0" // 没有padStr值,则为 0content = String(content) // 字符串return content.padStart(count, padStr) // 不够 count 位数,用 padStr 补齐}// 1.获取时间的元素var timeEl = document.querySelector(".time")setInterval(function() { // setInterval(fn,1000) 每过一秒钟执行一次// 2.获取具体的时间并且进行格式化var date = new Date()var year = date.getFullYear()var month = padLeft(date.getMonth() + 1)var day = padLeft(date.getDate())var hour = padLeft(date.getHours())var minute = padLeft(date.getMinutes())var second = padLeft(date.getSeconds())// 3.将时间放到timeEl中timeEl.textContent = `${year}-${month}-${day} ${hour}:${minute}:${second}`}, 1000);
9.9 的大小、滚动、坐标
(1)DOM元素
api | 含义 |
---|---|
clientWidth | contentWith+padding (不包含滚动条) |
clientHeight | contentHeight+ padding |
clientTop | border-top的宽度 |
clientLeft | border-left的宽度 |
offsetWidth | 元素完整的宽度 |
offsetHeight | 元素完整的高度 |
offsetLeft | 距离父元素的x |
offsetHeight | 距离父元素的y |
scrollHeight | 整个可滚动的区域高度 |
scrollTop | 滚动部分的高度 |
(2)window
window 的 width 和 height
- innerWidth、innerHeight >> 获取window窗口的宽度和高度 (包含滚动条)
- outerWidth、outerHeight >> 获取window窗口的整个宽度和高度 (包括调试工具、工具栏)
- documentElement.clientHeight、 documentElement.clientWidth >> 获取html的宽度和高度 (不包含滚动条)
window的滚动位置
- scrollX >> X轴滚动的位置 (别名pageXOffset)
- scrollY >> Y轴滚动的位置 (别名pageYOffset)
10 事件监听 略
ppt:12_JavaScript的事件监听.pdf
11 DOM 实战 略
ppt:13
12 BOM 操作 略
ppt:14
PPT 08 省略
90 document 语句
A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R、S、T、U、V、W、X、Y、Z
-
document.querySelector(“.box”) 元素选择器
-
document.write(“hhh”) 在视口打印
92 随手记函数
1、prompt 输入值
var inputInfo = prompt("请输入一个值")
console.log()
2、语法糖
语法糖的概念: 一种简写或者特殊的写法, 这种写法相对于原有的写法更加的方便或者阅读性更强
相比于原来的写法, 有一点点的甜头, 称之为语法糖
简写一亿(100000000) >> 1_0000_0000
封装工具函数: 对数字进行格式化
function formatCount(count) {var result = 0if (count >= 1_0000_0000) { // 超过1_0000_0000值进行转换result = Math.floor(count / 1_0000_0000) + "亿"} else if (count >= 10_0000) {result = Math.floor(count / 1_0000) + "万"} else {result = count}return result
}
3 debug
终极技巧:debug,代码出问题时,产生bug,debug找出bug
打断点:
方法一,代码里写 debugger
方法二,👇,34行代码不会执行
100 代码规范
- 函数规范
function foo(x, y) { // foo前空格 多参数","后空一格 参数")"后空一格 "{"与前面在同一行let result // 代码前面空两格
}
- 代码块之间空一行
- 反引号
``
之间,可以换行,可以加其他变量
var message = `
呼呼呼${bar}
`
这篇关于【coderwhy前端笔记 - 阶段二 JavaScript基础】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!