- alert 弹窗提醒一段文本
- a = prompt("input desc") 接收输入,并把内容赋值给 a
- confirm 弹出确认窗口,让用户确认,这是给出的结果就是 yes/no
- console.log('AAS') 输出一段日志
- let a = 1 声明 变量 a=1,number 类型
- const ABB = 123 声明一个常量 ABB, 不可以重新赋值
- undefined 和 null 都是空的意思,但是这两个又不相同
- a ?? "hello" ;
??
叫做 空值运算符,指当 a 未被赋值时,将 hello 赋值给 a,如果 a 已经被赋值了,则不变 ; a 需要被声明,在 JavaScript 中 声明 和 赋值 是两件事情
js 的数据类型
- js 是弱类型语言,1 == '1' => true; 但是 1 === '1' => false; 6 / "2" => 3, typeof is number
支持判断
if /elif else
支持的循环方式
do {
// Hello
} whIle ()
for (a=1;a<10;a+=2) {
// Hello
}
a = 100;
switch (a) {
case (a = 100):{
//Hello
break;
}
default:
alert(a);
}
函数声明
必须要使用 function
function showMessage() {
alert('Hello Javascript !');
}
- 函数中变量的作用域:这部分与 Python 和 C 一致,分别为 内部变量 和 外部变量;关系存在在继承的概念
- 函数的参数,入参定义在 () 内,当函数声明了入参后,在对应调用时,就需要传递符合条件的参数
- 支持函数的默认值的设定
- 函数的返回值,同样使用 return 作为返回值处理
- 函数 function is an action, 所以函数的命名通常是 使用动词;javascipt 的命名方式 官方建议为 驼峰的方式
函数的特殊部分
- 函数表达式 let sayHi = function () { alert('Hi')} 利用声明
let
创建了一个函数,并把他赋值给了变量 sayHi - 回调函数
[ ] 今天学习的内容到此 回调函数 https://zh.javascript.info/function-expressions
严格模式
- 三连表达式 cond ? resultA : resultB // 1 > 0 ? alert(true) : alert(false) cond 为真展示 resultA, 反之展示 resultB
- 空值运算符 a ?? b => a ?? b 的结果是 a,除非 a 为 null/undefined,这时结果是 b
开发行为规范
BDD
在 BDD 中,规范先行,实现在后。最后我们同时拥有了规范和代码。
规范有三种使用方式:
- 作为 测试 —— 保证代码正确工作。
- 作为 文档 —— describe 和 it 的标题告诉我们函数做了什么。
- 作为 案例 —— 测试实际工作的例子展示了一个函数可以被怎样使用。
有了规范,我们可以安全地改进、修改甚至重写函数,并确保它仍然正确地工作。
这在一个函数会被用在多个地方的大型项目中尤其重要。当我们改变这样一个函数时,没有办法手动检查每个使用它们的地方是否仍旧正确。
如果没有测试,一般有两个办法:
- 展示修改,无论修改了什么。然后我们的用户遇到了 bug,这应该是我们没有手动完成某些检查。
- 如果对出错的惩罚比较严重,并且没有测试,那么大家会很害怕修改这样的函数,然后这些代码就会越来越陈旧,没有人会想接触它。这很不利于发展。自动化测试则有助于避免这样的问题!
如果这个项目被测试代码覆盖了,就不会出现这种问题。在任何修改之后,我们都可以运行测试,并在几秒钟内看到大量的检查。
另外,一个经过良好测试的代码通常都有更好的架构。
当然,这是因为覆盖了自动化测试的代码更容易修改和改进。但还有另一个原因。
要编写测试,代码的组织方式应确保每个函数都有一个清晰描述的任务、定义良好的输入和输出。这意味着从一开始就有一个好的架构。
在实际开发中有时候可能并不 容易,有时很难在写实际代码之前编写规范,因为还不清楚它应该如何表现。但一般来说,编写测试使得开发更快更稳定。
Object 对象的基础知识
在 js 中 对象可以说非常常见的用到,所以相对来讲 定义一个对象也是非常的方便
let user = new Object(); 构造函数 的语法
let user = {} 构造 "字面量的语法"
在对象中,包含的是 一个个属性,这些属性又以 键值对 的形式出现在 中
- 定义一个有属性的对象
let user = {name:'alex', age: 18}
- 增加属性 user.city = 'Shanghai' => user['love package'] = 'Apple'
- 删除一个属性 delete user.age
- 计算属性 :当创建一个对象时,我可以在对象字面量中使用方括号,这叫做计算属性;计算属性的含义是 [fruit] 是从 变量 fruit 中获取的
- 判断一个 属性是否在对象中 "key" in Object ,这里的 key 需要时一个值,否则会被认为一个变量
- 遍历一个对象采用的方式是 for (let key in Object) : 这里的做法是 声明[let] 变量 key,并且把 Object 中的每一个 key 的值遍历赋予 key
- 取出对象中一个 key 的值可以采用的方式 Object[key] 或者 Object.key;但是 Object.key 会出现对
多词属性
- 单词属性 name , age
- 多词属性 "like birds" ,这时使用 Object.key 的方式就不可行了
JavaScirpt 中的垃圾回收机制
当一个对 象中的属性被建立后,如果这些属性被多个对象引用时,其他一个对象被重新赋值了,那么这些属性还是可以被访问的;但是当所有对象被重置后,这些无法被访问的属性 就变得不可以,这也会占用我们内存,而这类也会被 回收。
对象的方法 this
this 是用来标识当前对象的,这个对象可以是个函数 ; 为了访问该对象,方法中可以使用 this 关键字。
this 设计到编程的一种形式: **面向对象编程** OOP ; 当我们在代码中用对象表示实体时,就是所谓的 面向对象编程,简称为“OOP”。
- this 的优势:在 JavaScript 中,this 关键字与其他大多数编程语言中的不同。JavaScript 中的 this 可以用于任何函数,即使它不是对象的方法。
- this 的值是在代码运行时计算出来的,它取决于代码上下文。不用函数调用 this 时的到结果不一致的
- 箭头函数 function sum (a,b) => a*b;这类箭头函数是没有自己的 this,如果在箭头函数中使用 this,会把 this 当成一个真正的对象去处理,这不好
在 JavaScript 中,this 是“自由”的,它的值是在调用时计算出来的,它的值并不取决于方法声明的位置,而是取决于在“点符号前”的是什么对象。在运行时对 this 求值的这个概念既有优点也有缺点。一方面,函数可以被重用于不同的对象。另一方面,更大的灵活性造成了更大的出错的可能。这里我们的立场并不是要评判编程语言的这个设计是好是坏。而是要了解怎样使用它,如何趋利避害。
对象的 构造和操作符 new
- 构造函数在技术上,也是属于常规函数,不过有 2 个约定:
- 命名以大写字母开头,这是一个共同的约定,用来标明一个函数将被使用
new
来运行 - 他们只能有
new
操作符来执行
- 命名以大写字母开头,这是一个共同的约定,用来标明一个函数将被使用
构造器不能被再次调用,因为他保存在任何地址,知识被创建后 后续 调用使用;所以 构造函数的封装一个 单一对象的代码,而无需将来重用
JavaScript ?.
可选链
可选链 ?. 语法有三种形式:
- obj?.prop —— 如果 obj 存在则返回 obj.prop,否则返回 undefined。
- obj?.[prop] —— 如果 obj 存在则返回 obj[prop],否则返回 undefined。
- obj.method?.() —— 如果 obj.method 存在则调用 obj.method(),否则返回 undefined。
正如我们所看到的,这些语法形式用起来都很简单直接。?. 检查左边部分是否为 null/undefined,如果不是则继续运算。 ?. 链使我们能够安全地访问嵌套属性。但是,我们应该谨慎地使用 ?.,仅在当左边部分不存在也没问题的情况下使用为宜。以保证在代码中有编程上的错误出现时,也不会对我们隐藏。
Symbol 类型
根据规范,Obj 的属性键 只能是 字符串类型或者 Symbol 类型;不能是 Number,也不能是 Boolean。
Symbol 值 表示 唯一的标识符,现在可以通过 Symbol() 来创建这种类型的值;Symbol 的特性是唯一,即使我们创建了相同描述的 Symbol,他们的值不相同的;比如以下:
let id1 = Symbol('id')
let id2 = Symbol('id')
id1 == id2 // 结果是 false
Symbol 的另外一个特性是不会被自动转化为字符串;其实在 javascript 中大多数的数值都是可以进行字符串的 隐式转换
,但是使用 Symbol() 定义的一个字符,是不能够直接转化为 字符串的,可以使用 Symbol('id').toString()
来输出字符串。
原始类型的方法
在 JavaScript 中有 7 种原始类型:string,number,bigint,boolean,symbol,null 和 undefined。
- 字符串处理方法
- Number 的处理方法
数组方法的备忘笔记
数组方法备忘单:
-
添加/删除元素:
- push(...items) —— 向尾端添加元素
- pop() —— 从尾端提取一个元素
- shift() —— 从首端提取一个元素
- unshift(...items) —— 向首端添加元素
- splice(pos, deleteCount, ...items) 从 pos 开始删除 deleteCount 个元素,并插入 items。
用来控制数组的增删改查
- slice(start, end) —— 创建一个新数组,将从索引 start 到索引 end(但不包括 end)的元素复制进去
取出部分数组的内容产生新数组
- concat(...items) —— 返回一个新数组:复制当前数组的所有元素,并向其中添加 items。如果 items 中的任意一项是一个数组,那么就取其元素。
拼接多个数组,产生一个新的数组
-
搜索元素:
-
indexOf/lastIndexOf(item, pos) —— 从索引 pos 开始搜索 item,搜索到则返回该项的索引,否则返回 -1。
-
includes(value) —— 如果数组有 value,则返回 true,否则返回 false。
-
find/filter(func) —— 通过 func 过滤元素,返回使 func 返回 true 的第一个值/所有值。
-
findIndex 和 find 类似,但返回索引而不是值。
-
遍历元素:
- forEach(func) —— 对每个元素都调用 func,不返回任何内容。
let fruits = ['Apple', 'Orage','Prism']
for ( let fruit of fruits ) \{alert(fruit); \}
// 遍历数组 使用 for .. of 不能获取到当前元素的索引,知识获取到元素的值;但是大多数情况下是够用的,而且这样些代码更短,质量会高一些
for (let i = 0; i <= fruits.length; i++ ) \{alert(fruits[i])\}
// 这个方式就是标准的通过遍历元素的索引,然后通过索引获取到对应的数组元素的值
- 转换数组:
- map(func) —— 根据对每个元素调用 func 的结果创建一个新数组。
- sort(func) —— 对数组进行原位(in-place)排序,然后返回它。
- reverse() —— 原位(in-place)反转数组,然后返回它。
- split/join —— 将字符串转换为数组并返回。
- reduce/reduceRight(func, initial) —— 通过对每个元素调用 func 计算数组上的单个值,并在调用之间传递中间结果。
- 其他:
- Array.isArray(arr) 检查 arr 是否是一个数组。
请注意,sort,reverse 和 splice 方法修改的是数组本身;这些是最常用的方法,它们覆盖 99% 的用例。但是还有其他几个:
- arr.some(fn)/arr.every(fn) 检查数组。
与 map 类似,对数组的每个元素调用函数 fn。如果任何/所有结果为 true,则返回 true,否则返回 false。
这两个方法的行为类似于 || 和 && 运算符:如果 fn 返回一个真值,arr.some() 立即返回 true 并停止迭代其余数组项;如果 fn 返回一个假值,arr.every() 立即返回 false 并停止对其余数组项的迭代。
我们可以使用 every 来比较数组:
function arraysEqual(arr1, arr2) {
return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);
}
alert( arraysEqual([1, 2], [1, 2])); // true
- arr.fill(value, start, end) —— 从索引 start 到 end,用重复的 value 填充数组。
- arr.copyWithin(target, start, end) —— 将从位置 start 到 end 的所有元素复制到 自身 的 target 位置(覆盖现有元素)。
- arr.flat(depth)/arr.flatMap(fn) 从多维数组创建一个新的扁平数组。
- Array.of(element0[, element1[, …[, elementN]]]) 基于可变数量的参数创建一个新的 Array 实例,而不需要考虑参数的数量或类型。