javaScript学习笔记
表达式和语句
- 表达式是一段可以求值产生的代码
- 语句是一段可以执行并执行某种动作的代码
- 表达式可以作为语句使用,这种情况称之为表达式语句
- 以function和{开头的语句不能解释为表达式
/*
注意区分:【js语句(代码)】与【js表达式】
1.表达式:一个表达式会产生一个值,可以放在任意一个需要值的地方
下面这些都是表达式:(1).a (2).a+b (3).demo(1) (4).arr.map() (5).function test() {}
2.语句(代码):
下面这些都是语句(代码):(1).if(){} (2).for(){}
*/
变量和赋值
- let声明可变变量,不允许重复声明
- const声明常量;const仅仅意味着绑定(变量名和变量值之间的关系)是不可变的,变量值本身是有可能改变的,当值是对象或数组的时候值是可以改的(如果想让整个对象都不能修改,可以使用 Object.freeze())
- const它声明变量时必须同时初始化变量,不允许重复声明,声明的作用域也是块
- 正常情况下都用const,只有明确这个变量需要更改才用let,循环的时候用let(i++)
- let 声明的范围是块作用域, 而 var 声明的范围是函数作用域。
- let 与 var 的另一个重要的区别,就是 let 声明的变量不会在作用域中被提升
- 使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)
- 对于 let 这个新的 ES6 声明关键字,不能依赖条件声明模式
- var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
数据类型有哪些
基本数据类型:字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol、对象(Object)、
- ECMAScript 提供了 isNaN()函数。该函数接收一个参数,可以是任意数据类型,然后判断 这个参数是否“不是数值”。
- 数值转换
- 有 3 个函数可以将非数值转换为数值:Number()、parseInt()函数更专注于字符串是否包含数值模式和、parseFloat()函数的工作方式跟 parseInt()函数类似,都是从位置 0 开始检测每个字符。同样, 它也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止,parseFloat()只解析十进制值。
- 对象,调用 valueOf()方法,并按照上述规则转换返回的值。如果转换结果是 NaN,则调用 toString()方法,再按照转换字符串的规则转换。
- toString()方法可见于数值、布尔值、对象和字符串值。null 和 undefined 值没有 toString()方法。如果你不确定一个值是不是 null 或 undefined,可以使用 String()转型函数,它始终会返回表 示相应类型值的字符串
- ECMAScript 6 新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同,模板字面量保留换行字符,可以跨行定义字符串
数组
-
在数组里没有要求是同一个类型,数组元素可以同时有字符串、数字、数组等
-
创建数组的方式
- 通过数组字面量(在使用数组字面量表示法创建数组不会调用Array构造函数)
- 通过new Array()创建数组
- 当我们给new Array()传递单个数字参数时,这个数字不是作为数组元素,而是该数组的length属性而存在,而数组本身则是一个空数组。
- 创建数组的静态方法:from()用于将类数组结构转换为数组实例,而 of()用于将一组参数转换为数组实例。
-
数组 length 属性的独特之处在于它不是只读的。通过修改 length 属性,可以从数组末尾删除或添加元素
-
Array 的原型上检索数组内容的方法:keys()、values()和 entries()。keys()返回数组索引的迭代器,values()返回数组元素的迭代器,而 entries()返回 索引/值对的迭代器
使用 ES6 的解构可以非常容易地在循环中拆分键/值对: const a = ["foo", "bar", "baz", "qux"]; for (const [idx, element] of a.entries()) { alert(idx); alert(element); } 注意 虽然这些方法是ES6规范定义的,但在2017年底的时候仍有浏览器没有实现它们。
-
ES6 新增了两个方法 : 批量复制方法 copyWithin(),以及填充数组方法 fill()
-
使用 fill()方法可以向一个已有的数组中插入全部或部分相同的值
arr.fill(value, start, end) /*value:填充值。 start:填充起始位置,可以省略。 end:填充结束位置,可以省略,实际结束位置是end-1。*/
-
copyWithin()会按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置
-
-
所有对象都有 toLocaleString()、toString()和 valueOf()方法
-
组有两个方法可以用来对元素重新排序:reverse()[反向排序]和 sort()
- sort()会在每一项上调用 String()转型函数,然后比较字符串来决定顺序(用于对数组的元素进行排序。)
-
操作方法
- concat()方法可以在现有数组全部元素基础上创建一个新数组
- slice()用于创建一个包含原有数组中一个或多个元素的新数组
-
搜索和位置方法
- 严格相等
- indexOf()方法从数组前头(第一项) 开始向后搜索,返回要查找的元素在数组中的位置,如果没找到则返回-1
- includes()方法从数组前头(第一项) 开始向后搜索,返回布尔值,表示是否至少找到一个与指定元素匹配的项
- lastIndexOf()从数组末尾(最后一项)开始向前搜索,返回要查找的元素在数组中的位置,如果没找到则返回-1
- 断言函数
- 断言函数接收 3 个参数:元素、索引和数组本身
- find()返回第一个匹配的元素
- findIndex()返回第一个匹配元素的索引
- 严格相等
-
迭代方法
- every():对数组每一项都运行传入的函数,如果对每一项函数都返回 true,则这个方法返回 true。
- filter():【过滤】对数组每一项都运行传入的函数,函数返回 true 的项会组成数组之后返回。(这个方法非常适合从数组中筛选满足给定条件的元素)
- forEach():对数组每一项都运行传入的函数,没有返回值。
- map():以函数为参数,对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组。
- some():对数组每一项都运行传入的函数,如果有一项函数返回 true,则这个方法返回 true。
-
归并方法
- reduce()【对数组进行条件统计、条件求和、筛选最值】和 reduceRight()。这两个方法都会迭代数组的所有项,并在此基础上构建一个最终返回值。reduce()方法从数组第一项开始遍历到最后一项。 而 reduceRight()从最后一项开始遍历至第一项(给一个值,然后返回新值)
-
遍历数组
- for循环
for (let i = 0; i < arr.length; i++)
- for in 用于枚举对象中的非符号键属性
//打印属性 会把继承过来的属性打印出来 for (const a in obj) { console.log(a); } //打印属性值 for (const prop in obj) { console.log(obj.[prop]); }
-
for-of方法:不需要索引 (用于遍历可迭代对象的元素)
for(const val of arr){ console.log(val+"\n") }
- for循环
-
为数组增加一个元素
//从后面增加 和栈比较类似 arr.push(5); //从后面删除 arr.pop(5); //从前面增加 arr.unshift(1); //从前面删除 arr.shift(1); //从中间增加 arr.splice(2, 0,10); //第一个参数是索引,第二个参数是删除的个数,第三个数是添加的值。
函数
- this方法
- 默认绑定,window全局对象
- 隐式绑定,指向调用该方法的对象
- 硬绑定:call和apply
- 构造函数绑定
//函数定义语句
function add(num1, num2){
return num1 + num2;
}
console.log(add(11, 13));
//函数表达式形式
const minus = function(num1, num2){
return num1 - num2;
}
console.log(minus(116, 13));
//箭头函数
const minus = (num1, num2) =>{
return num1 - num2;
}
console.log(minus(116, 13));
//也可以写成
const minus = (num1, num2) => num1 - num2;
//立即调用的函数表达式
(function() { // 块级作用域
})();
- 箭头函数不能使用 arguments、super 和 new.target,也不能用作构造函数,箭头函数也没有 prototype 属性。
- 箭头函数没有自己的this,箭头函数在哪个对象中调用,this就属于哪个对象
- arguments,访问函数参数值。(不是真正的数组)
//参数中用...arr,则可以表示真正的数组
function add() {
let result = 0;
for (let i = 0; i < arguments.length; i++){
result += arguments[i];
}
return result;
}
console.log(add(11, 13, 1, 3, 4));
- reduce() 方法
- reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
- reduce() 可以作为一个高阶函数,用于函数的 compose。
- reduce() 对于空数组是不会执行回调函数的。
- caller:这个属性引用的是调用当前函数的函数,或者如果是在全局作用域中调用的则为 null。
- 函数属性与方法
- 每个函数都有两个属性:length 和 prototype,length 属性保存函数定义的命名参数的个数,prototype 是保存引用类型所有实例方法的地方
- prototype 属性是不可枚举的,因此使用 for-in 循环不会返回这个属性
- bind(),方法返回生成一个新的函数对象;改变this指向
- apply()方法和call方法
- Function.apply(obj,args)方法能接收两个参数。obj:这个对象将代替Function类里this对象,args:这个是数组,它将作为参数传给Function(args–>arguments)
- Function.call(obj,[param1[,param2[,…[,paramN]]]])。obj:这个对象将代替Function类里this对象,params:这个是一个参数列表
- 什么情况下用apply,什么情况下用call
- 在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));
- 使用 call()或 apply()的好处是可以将任意对象设置为任意函数的作用域,这样对象可以不用关心方法。
- 递归
- arguments.callee就是一个指向正在执行的函数的指针,因此可以在函数内部递归调用
function factorial(num){
if(num <= 1){
return 1;
}else{
return num * arguments.callee(num-1);
}
}
var trueFactorial = factorial;
alert(trueFactorial(5)); //120
factorial = function() {
return 0;
}
alert(trueFactorial(5));// 120 如果没有使用arguments.callee,将返回0
-
闭包:指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的
-
使用闭包和私有变量会导致作用域链变长,作用域链越长,则查找变量所需的时间也越多。
-
闭包的作用域链中包含自己的一个变量对象,然后是包含函数的变量对象,直到全局上下文的变量对象。
-
闭包在被函数返回之后,其作用域会一直保存在内存中,直到闭包被销毁。(参数和变量不会被垃圾回收机制回收)
-
虽然 JavaScript 没有私有对象属性的概念,但可以使用闭包实现公共方法,访问位于包含作用域中定义的变量
- 可以访问私有变量的公共方法叫作特权方法。
-
闭包的作用
- 实现公有变量: eg:函数累加器
- 可以做缓存(存储结构):eg:eater
- 可以实现封装,属性私有化:eg:new Person();
- 模块化开发,防止污染全局变量
-
-
模块模式
- 单例对象(singleton)就是只有一个实例的对象。
- 模块模式是在单例对象基础上加以扩展,使其通过作用域链来关联私有变量和特权方法。
运算符和流程控制
大部分运算符的操作数是基本类型的值,当操作数是对象的时候,通常把它转换成几本类型的值。运算符会将其操作数强制转换为适当类型。
-
(解构赋值)
const arr = [11, 12, 13, 1, 2]; //使编码更加方便 const [one, two, ...rest] = arr; //对象也可以 const obj = { one: 1; two: 2; }; const [one, two] = obj;
-
有符号左移右移(<< 、>> )无符号位左移右移(<<< 、>>>)
-
任何情况下判断相等都用三个等号,两个等号允许存在类型转换
-
js中不存在整除
-
类型转换,‘+’ 可以进行转换,字符串转换成数字建议用
Number()
函数 -
** 代表乘方的计算
5**2
-
十进制改成二进制
let a = 10;
a.toString(2); //括号里代表转换成几进制
- &&运算,两边都是真值返回ture,有一个假值就返回false;前面的值如果是真值就会返回后面的值,前面的值是个假值就会返回前面那个。
- 如果第一个操作数是对象,则返回第二个操作数。
- 如果第二个操作数是对象,则只有第一个操作数求值为 true 才会返回该对象。
- 如果两个操作数都是对象,则返回第二个操作数。
- 如果有一个操作数是 null,则返回 null。
- 如果有一个操作数是 NaN,则返回 NaN。
- 如果有一个操作数是 undefined,则返回 undefined。
- 逻辑或与逻辑与类似,如果有一个操作数不是布尔值,那么逻辑或操作符也不一定返回布尔值
- 如果第一个操作数是对象,则返回第一个操作数。
- 如果第一个操作数求值为 false,则返回第二个操作数。[短路或]
- 如果两个操作数都是对象,则返回第一个操作数。
- 如果两个操作数都是 null,则返回 null。
- 如果两个操作数都是 NaN,则返回 NaN。
- 如果两个操作数都是 undefined,则返回 undefined。
- 将其他值转换为布尔值
Boolen(x)
; - 字符串拼接
const a = 'hello';
console.log(a + 'world');
//ES6
console.log(`${a} world`);
- delete,删除对象的属性;判断属性名是否是对象的属性用in
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上。instanceof 操作符可以用来确定一个对象实例的原型链上是否有原型
基本引用类型
Date
- 继承的方法
- Date 类型的 toLocaleString()方法返回与浏览器 运行的本地环境一致的日期和时间。
- oString()方法通常返回带时区信息的日期和时 间,而时间也是以 24 小时制(0~23)表示的
- 日期格式化方法
- toDateString()显示日期中的周几、月、日、年(格式特定于实现);
- toTimeString()显示日期中的时、分、秒和时区(格式特定于实现);
- toLocaleDateString()显示日期中的周几、月、日、年(格式特定于实现和地区);
- toLocaleTimeString()显示日期中的时、分、秒(格式特定于实现和地区);
- toUTCString()显示完整的 UTC 日期(格式特定于实现)。
- 日期/时间组件方法
变量、作用域与内存
原始值与引用值
原始值就是最简单的数据,共有六种(Undefined、Null、Boolean、Number、String 和 Symbol),引用值则是由多个值构成的对象。原始值大小固定,因此保存在栈内存上,引用值是对象,存储在堆内存上。
-
动态属性:对于引用值而言,可以随时添加、修改和删除其属性和方法。
-
复制值:把引用值从一个变量赋给另一个变量时,存储在变量中的值也会被复制到新变量所在的位置。这里复制的值实际上是一个指针,它指向存储在堆内存中的对象,两个变量实际上指向同一个对象。
-
确定类型:
-
typeof 检测原始值对引用值的用处不大。通过 instanceof 操作符检测任何引用值和 Object 构造函数都会返回 true。如果用 instanceof 检测原始值,则始终会返回 false, 因为原始值不是对象。
-
typeof操作符在用于检测函数时也会返回"function"。
-
typeof 对正则表达式也返回"function"。在 IE 和 Firefox 中,typeof 对正则表达式 返回"object"。
-
执行上下文与作用域
- 执行上下文在其所有代码都执行完毕后会被销毁,包括定义 在它上面的所有变量和函数
- 全局上下文在应用程序退出前才会被销毁,比如关闭网页或退出浏览器。
- 上下文中的代码在执行的时候,会创建变量对象的一个作用域链,代码正在执行的上下文的变量对象始终位于作用域 链的最前端。全局上下文的变量对象始终是作用域链的最后一个变量对象。
- 作用域链增强
- try/catch 语句的 catch 块:则会创建一个新的变量对象,这个变量对象会包含要抛出的错误对象的声明
- with 语句(用途是将代码作用域设置为特定的对象):会向作用域链前端添加指定的对象
垃圾回收
- 离开作用域的值会被自动标记为可回收,然后在垃圾回收期间被删除。
- 主流的垃圾回收算法是标记清理,即先给当前不使用的值加上标记,再回来回收它们的内存
- 引用计数在代码中存在循环引用时会出现问题。
- 解除变量的引用不仅可以消除循环引用,而且对垃圾回收也有帮助。为促进内存回收,全局对象、全局对象的属性和循环引用都应该在不需要时解除引用。
单例内置对象
内置对象,包括 Object、Array 和 String。
对象
在js中对象就是属性的结合(键值对 key->value)key可以是字符串和symbol;对象可以扮演两个角色,一个是作为记录,一个是作为字典
- js中不用声明一个类,直接就可以创建对象。
- 创建对象的方法
- 对象字面量 (在使用对象字面量表示法定义对象时,并不会实际调用Object构造函数)
new Object()
,等同于对象字面量,都是创建对象实例Object.create(object,properties)
const firstName = 'cui';
function getFullName() {
return `${this.firstName} ${this.lastName}`;
}
const people = {
firstName, //属性值缩写
lastName: 'b',
getFullName,
//访问器属性
get fulNanme() {
return `${this.firstName} ${this.lastName}`;
},
set fulNanme(str) {
const [firstName, lastName] = str.split(' ');
this.firstName = firstName;
this.lastName = lastName;
}
}
people.sex = 'male';
people.fulNanme = 'tes111 test'
console.log(people);
- 一般用 . 和 [ ] 去访问对象属性
- …运算符:展开运算符
const obj = {
a: 1,
b: 2
}
const obj1 = { ...obj }
console.log(obj === obj1)
//两个对象是不等的,对象属于一个引用类型,比较的不是两个对象的值,而是两个对象的引用。
-
访问器属性(访问器属性可以起到很好的保护作用)
- 在setter函数体中,一切的return都是无效的,只有setter函数时,表示属性是只写的,只有getter函数时,表示属性是只读的,同时有setter、getter函数,表示属性可读可写。
- 在get和set中使用this会导致无限递归,内存溢出
- 访问器属性和数据属性value不能同时定义,也不能多次定义,两者只可定义一种
-
计算属性:可以理解为能够在里面写一些计算逻辑的属性。
-
in操作符,检测属性有没有在对象里面。
-
hasOwnProperty()方法用于确定某个属性是在实例上还是在原型对象上。
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHT9FYqB-1622299854870)(/Users/wangpeizhen/O.Olivia/notes/11.前端基础笔记/pic/07.js对象1.png)]
Object.key()参数是跟一个对象,打印的是自身的属性。
- 检测
- propertylsEnumerble()检测属性是否可以被枚举
- hasOwnProperty() 判断是否为自身的属性
- In运算符 检测是否有这个属性
- 检测
-
Object实例属性
- .constructor:检测是哪个类创造的
._proto_
-
Object实例方法
- .toString() 运算符需要转成字符串
- .toLocaleString()
- .valueOf() 运算符需要转成数字
-
Object静态属性
Object是最基本的对象,本质上也属于函数
- Object.length:定义的参数个数
- Object.prototrype
-
Object静态方法 (静态方法是无法被子类继承或者实例对象拥有的)
-
Object.is(value1, value2),判断两个变量是否指向同一个对象
-
Object.values(obj),返回所有的属性值。Object.entries()返回键/值对的数组
-
Object.keys(obj),返回所有的属性名
-
Object.assign()方法。
- 合并多个对象
const obj1 = { name: '张三',age: 20} const obj2 = { address: '广东深圳', hobby: 'code' } const obj3 = { workingYears: 5} const obj = Object.assign(obj1, obj2, obj3) console.log(obj) //{ name: '张三', age: 20, address: '广东深圳', hobby: 'code', workingYears: 5}
- 克隆对象(浅)
const obj = { name: '张三' ,age: 20} const obj1 = Object.assign({},obj) console.log(obj1) //{ name: '张三' ,age: 20}
- 为对象添加多个方法
Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { }, anotherMethod() { } }); // 原来的方法 SomeClass.prototype.someMethod = function (arg1, arg2) { }; SomeClass.prototype.anotherMethod = function () { };
-
Object.getPrototypeOf(obj) 获得obj的原型,也可以使用obj._ proto__属性获得obj的原型
-
Object.getOwnPropertyNames(obj) 可以将obj的可枚举和不可枚举的属性的名称组成一个数组返回
-
Object.defineProperty(obj, propName, desc) 该方法可以为obj新增一个名为propName的属性,同时它的属性定义为desc,desc使用一个对象赋值。在调用Object.defineProperty()时,configurable、enumerable和writable的值如果不 指定,则都默认为 false。
-
Object.create(proto,[props]) 以proto为原型,新建一个实例对象,同时将props定义的属性设置给这个新对象,以这种方式新建的对象都是Object类型
-
Object.getOwnPropertyDescriptor(obj,propName) 这个方法实际上会在每个自有属性上调用Object.getOwnPropertyDescriptor()并在一个新对象中返回它们。
-
Object.preventExtensions(obj) 可以禁止obj对象的属性扩展
-
Object.seal(obj) 可以禁止obj对象的属性扩展和删除,它相对与preventExtensible方法而言 ,将所有属性的configurable属性设置为false
-
Object.freeze(obj) 可以禁止对obj的所有操作,它相对与preventExtensible方法而言,将属性的configurable属性和writable属性都设置为了false
-
构造函数和原型
构造函数
构造函数名称的首字母都是要大写的,非构造函数则以小写字母开头
- 构造函数的问题
- 构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍。
- new constructor
- 创建一个js空对象
- 设置空对象的constructor属性
- 将这个对象作为this执行构造函数
- 如果函数没有显示直接返回一个对象,则返回this
原型(prototype)对象
- 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应一个对象,这个对象就是我拼命所谓的原型对象
- 如果函数作为普通函数调用prototype没有任何作用,当函数以构造函数函数的形式调用时,它所创建的对象中会有i个隐含的属性,指向该构造函数的原型对象,我们可以通过
__proto__
来访问该属性
继承
- 盗用构造函数
- 在子类构造函数中调用父类构造函数。使用 apply()和 call()方法以新创建的对象为上下文执行构造函数。
BOM(浏览器对象模型 : 提供与浏览器交互的方法和接口)
-
BOM提供了很多对象,用于访问浏览器的功能,这些功能与任何网页内容无关。
-
BOM 主要针对浏览器窗口和子窗口(frame)
弹出新浏览器窗口的能力; 移动、缩放和关闭浏览器窗口的能力; navigator 对象,提供关于浏览器的详尽信息; location 对象,提供浏览器加载页面的详尽信息; screen 对象,提供关于用户屏幕分辨率的详尽信息; performance 对象,提供浏览器内存占用、导航行为和时间统计的详尽信息; 对 cookie 的支持; 其他自定义对象,如 XMLHttpRequest 和 IE 的 ActiveXObject。
-
要引用其他 window 对象,可以使用几个不同的窗口指针。
-
window对象
-
定时器
-
setTimeout()用于指定在一定时间后执行某些代码,而 setInterval()用于指定每隔一段时间执行某些代码。
//要执行的代码和在执行回调函数前等待的时间(毫秒) // 设置超时任务 let timeoutId = setTimeout(() => alert("Hello world!"), 1000); // 取消超时任务 clearTimeout(timeoutId); setInterval(function(){ alert("Hello"); }, 3000); //每三秒(3000 毫秒)弹出 "Hello"
-
异步任务分为宏任务和微任务,微任务优先级高于宏任务
-
-
系统对话框
- 使用 alert()、confirm()[确认框]和 prompt()[提示框]方法,可以让浏览器调用系统对话框向用户显示消息。
-
-
location对象
- window.location 和 document.location 指向同一个对象
- 查询字符串
- URLSearchParams 提供了一组标准 API 方法,通过它们可以检查和修改查询字符串。
- 操作地址
- assign()方法、reload()方法
- 通过 location 对象可以以编程方式操纵浏览器的导航系统。通过设置这个对象上的属性,可以改变浏览器 URL 中的某一部分或全部。
- 使用 replace()方法可以替换浏览器历史记录中当前显示的页面,并导航到新 URL。
- window.onload方法
-
navigator对象
- navigator 对象的属性通常用于确定浏览器的类型。
- navigator 对象提供关于浏览器的信息。提供的信息类型取决于浏览器,不过有些属性如 userAgent 是所有浏览器都支持的。
-
screen 对象中保存着客户端显示器的信息。这些信息 通常用于评估浏览网站的设备信息。
-
history对象
- history 对象表示当前窗口首次使用以来用户的导航历史记录。
- 导航
- go()方法可以在用户历史记录中沿任何方向导航,可以前进也可以后退。
- go()有两个简写方法:back()和 forward()。
- history 对象通常被用于创建“后退”和“前进”按钮,以及确定页面是不是用户历史记录中的第一条记录。
- history 对象提供了操纵浏览器历史记录的能力,开发者可以确 定历史记录中包含多少个条目,并以编程方式实现在历史记录中导航,而且也可以修改历史记录。
DOM(文档对象模型 : 提供与网页内容交互的方法和接口)
- DOM是针对HTML(超文本标记语言)和XML(可扩展标记语言)文档的一个API(应用程序编程接口)。
- DOM 通过创建表示文档的树,让开发者可以随心所欲地控制网页的内容和结构。使用 DOM API可以轻松地删除、添加、替换、修改节点。
节点层级
- 在 HTML 页面中,文档元素始终是元素。在 XML 文档中, 则没有这样预定义的元素,任何元素都可能成为文档元素。
节点操作
-
增:增加页面标签对象
-
document.createElement()
创建标签对象 -
HTMLElement.appendChild()
方法。既然appendChild是`HTMLElement对象下的方法那么全部的标签都可以用这个方法来添加子元素。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BrdOJoa9-1622299854871)(/Users/wangpeizhen/O.Olivia/notes/11.前端基础笔记/pic/09.DOM.png)]
-
-
删:移除页面标签对象
HTMLElement.removeChild()
方法
-
查:用选择器去查找
-
改:改变一个标签对象的属性
- 属性,可以通过赋值的方式改变。HTMLElement常用的属性style,className,id,innerHTML,innerText。
-
通用的获取和改变属性的方法
- 获取:
HTMLElement.getAttribute()
- 改变:
HTMLElement.setAttribute()
- 获取:
-
getElementsByTagName() [获取标签元素]方法可返回带有指定标签名的对象的集合。getElementsByTagName() 方法返回元素的顺序是它们在文档中的顺序。如果把特殊字符串 “*” 传递给 getElementsByTagName() 方法,它将返回文档中所有元素的列表,元素排列的顺序就是它们在文档中的顺序。
js选择器
- id选择器
documet.getElemetByID("")
- class选择器
documet.getElemetsByClassName()
- 标签选择器
documet.getElemetsByTagName()
documet.querySelector("#d1")
以css选择器方式来选择页面元素documet.querySelectorAll(".d1")
事件
-
事件流
- IE 事件流被称为事件冒泡
- 事件捕获的事件流,最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。
- DOM 事件流
- 规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。
-
事件监听器
- on事件属性和
addEventlistener()
方法- addEventListener(事件名,函数名,布尔值),方法用于向指定元素添加事件句柄。布尔值不写默认为false 【false 是事件冒泡,ture是事件捕获】
- 区别:因为on事件是一个属性,所以只能赋值,赋值就会替换掉;简单说,on事件只能挂一个,addEventListener对一个事件重复挂多个
- on事件属性和
-
键盘事件一般挂在doucument下
-
表单事件(用户登陆输入密码验证)
- focus输入框获得焦点
- blur失去焦点
- input内容输入
- onchange 事件会在域的内容改变时发生
- onchange 事件也可用于单选框与复选框改变后触发的事件
- onsubmit 事件在表单提交时触发。
-
页面事件
- 页面的加载顺序
- 解析html结构
- 加载,解析js
- dom构建完成执行js
- 加载图片样式表
- 页面加载完成
- 页面的加载顺序
-
this和event.target的区别
- js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的目标DOM元素;
模块化编程
- ES6模块化语法,如果用默认暴露暴露的名字可以更改
- 在入口中引入样式,不用变量接,不用写from
- 在入口中引入json,
improt a from '../json/test.json'
- loader特点:下载后无需引入只需声明
客户端存储
cookie
cookie:是存储在本地的数据,有时候也用cookies,通常经过加密,应用最经典的就是判断注册用户是否已经登录过该网站。
- documet.cookie="name=skipper;expires=[GTM日期格式]"键,值,过期时间
- 设置cookie:直接对documet.cookie赋值(key不会被覆盖)
- 获取cookie:因为cookie是一个字符串,所以只能对字符串进行分析
遵守以下大致的限制,就不会在任何浏览器中碰到问题:
- 不超过 300 个 cookie;
- 每个 cookie 不超过 4096 字节;
- 每个域不超过 20 个 cookie;
- 每个域不超过 81 920 字节。
每个域能设置的 cookie 总数也是受限的,但不同浏览器的限制不同。例如:
- 最新版 IE 和 Edge 限制每个域不超过 50 个 cookie;
- 最新版 Firefox 限制每个域不超过 150 个 cookie;
- 最新版 Opera 限制每个域不超过 180 个 cookie;
- Safari 和 Chrome 对每个域的 cookie 数没有硬性限制。
Window localStorage 属性
使用 localStorage 创建一个本地存储的 name/value 对,name=“lastname” value=“Smith”, 然后检索 “lastname” 的值,并插入到 id=“result” 的元素上:
// 存储localStorage.setItem("lastname", "Smith");// 检索document.getElementById("result").innerHTML = localStorage.getItem("lastname");
- localStorage 和 sessionStorage 属性允许在浏览器中存储 key/value 对的数据。
- localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。
- localStorage 属性是只读的。
- sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
HTTP协议
- 请求
- 请求行
GET URL HTTP/1.1
- 请求头
- 空行
- 请求体 【如果是GET请求,请求体是空的;post可以为空,也可以不为空】
- 请求行
- 响应
Ajax
-
安装express框架
-
优点
- 页面无刷新的情况下向服务端发送http请求获取数据
- 允许你根据用户事件来更新部分页面内容
-
缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好(搜索引擎优化)
-
发送ajax请求步骤
- 创建对象
const xhr = XMLHttpRequest();
- 设置初始化 请求方法和URL
xhr.open('GET', 'http://127.0.0.1:8000/server');
- 发送
xhr.send();
- 事件绑定处理服务端返回的结果
xhr.onreadystatechange = function(){ }
on when
当…的时候。 readystate是xhr对象中的属性,表状态0 1 2 3 4 ,一共会出发四次。
- 创建对象
-
在AJAX请求中如何设置URL参数
- 在URL中坠参数,用?分割,如果有多个参数用&分割
http://127.0.0.1:8000/server?a=100&b=200
- 在URL中坠参数,用?分割,如果有多个参数用&分割
-
在AJAX请求中设置请求头:
xhr.setRequestHeader('头的名字','头的值');
-
json字符串转成对象
- 手动转换
let date = JSON.parse(xhr.response)
- 自动转换
xhr.responseType = 'json'; result.innerHTML =xhr.response.name
- 手动转换
-
Nodemon安装:
npm install -g nodemon
[免去重新启动服务] -
ie浏览器缓存问题:在向服务端发送请求,服务端返回数据时ie浏览器会把数据放置放置缓存中,影响页面的更新,添加时间戳让ie浏览器认为每次发送的是新的请求。
-
请求超时与网路异常问题
Promise
- 是js中进行异步编程的新解决方案(旧的用的都是回调函数的方式)
- 从语法上来说promis是一个构造函数;从功能上来说promis对象用来封装一个异步操作并可以获取成功/失败的结果值
异步编程
- fs文件操作(fs是node.js下边的一个模块,可以对磁盘进行操作)
- 数据库操作
- AJAX
- 定时器
为什么要用Promise?(面试)
- 指定回调函数的方式更加灵活
- 旧的:必须在启动异步任务前指定;
- Promise:启动异步任务=>返回Promise对象=>给Promise对象绑定回调函数(甚至可以在异步任务结束后指定多个)
- 支持链式调用,解决回调地狱问题
前端路由实现的两种方式
JavaScript
<script type="text/javascript">
var str="How are you doing today?"
document.write(str.split(" ") + "<br />")
document.write(str.split("") + "<br />")
document.write(str.split(" ",3))
</script>
输出:
How,are,you,doing,today?
H,o,w, ,a,r,e, ,y,o,u, ,d,o,i,n,g, ,t,o,d,a,y,?
How,are,you