共计 6618 个字符,预计需要花费 17 分钟才能阅读完成。
1.JavaScript 简介
1.1 javascript 的组成部分
(1)ECMAScript, 形容了该语言的语法和根本对象
(2) 文档对象模型(DOM), 形容解决网页内容的办法和接口
(3) 浏览器对象模型 (BOM), 形容与浏览器进行交互的办法和接口。
1.2 javascript 的特点
(1) 解释型语言,nodejs 为其解释器
(2) 弱类型语言,变量的数据类型取决于值的数据类型
a. 变量的数据类型在初始化的时候确定
b. 变量得数据类型能够随时发生变化
c. 类型细分不显著
(3) 按程序解释执行,即从上到下执行
(4) 既能够作为前端脚本语言,也能够作为后端语言,取决于利用平台和应用的框架
1.3 在 body 和 head 中应用 JavaScript 的区别
(1) 在 body 局部中的 JavaScript 会在页面加载的时候被执行,在 head 局部中的 JavaScript 会在被调用的时候才执行。(2) 浏览器解析 Html 是从上到下解析的。把 JavaScript 放在 head 里时,则先会被解析,但因为这时 body 还没有解析,所以会返回空值。个别都会绑定一个监听,当全副的 html 文档解析完之后再执行代码。
1.4 JavaScript 数据类型
(1)5 个根本数据类型(值类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(es6 中新增,示意举世无双的值)
(2) 援用数据类型:对象(Object)、数组(Array)、函数(Dunction)
1.5 Undefined 与 Null 关系
(1)undefined 继承 null, 所以 undefined==null 后果为 true, 然而 null 示意空对象,undefined 示意未定义
(2)null 与 undefined 用处不同,null 能够用来示意一个空对象,然而没有必要把一个变量的值显式设置为 undefined。(3)undefined===null 为 false,因为类型不同。
1.6 实现深拷贝的办法
(1) 通过 json 对象实现深拷贝(JSON.stringify,JSON.parse)(2)Object.assign() 拷贝
(3)lodash 函数库实现深拷贝
(4) 递归的形式实现深拷贝
2 操作符及类型转换
2.1 操作符
2.1.1 算数运算符 (5 种)
(1) + 加法
(2) - 减法
(3) * 乘法
(4) / 除法
(5) % 取余
2.1.2 一元运算符 (8 种罕用)
(1) + 将操作数转换成数字,字符串的拼接
(2) - 将操作数转换成数字,同时变为正数
(3)!逻辑取反运算
(4) ++ 递增
(5) -- 递加
(6) delete 删除数组或对象中特定索引的值
(7) typeof 返回以后操作数的类型
(8) void void 运算符对任何值返回 undefined
2.1.3 赋值运算符(6 种)
(1) =
(2) +=
(3) -=
(4) *=
(5) /=
(6) %=
2.1.4 比拟运算符 (8 种)
(1) == 等于
(2) === 值相等并且类型相等
(3) != 不相等
(4) !== 值不相等或类型不相等
(5) > 大于
(6) < 小于
(7) >= 大于或等于
(8) <= 小于或等于
2.1.5 逻辑运算符
(1) && and(同真才真,有假则假)
(2) || or(有真才真,有假则假)
(3) ! not
2.2 JavaScript 隐式转换
2.2.1 原始类型转换
(1) 加减乘除:1. 字符串加数字, 数字就会转成字符串。数字加数字或字符串加字符串不须要转换。在加法的过程中,首先把等号左右两边进行了求原值 ToPrimitive() 操作,而后如果有两个或多个原始值只有有一个是 String 类型,就把两个或多个原始值都进行转化字符串 toString() 操作,进行字符串拼接;否则把两个或多个原始值都进行转化数字 toNumber() 操作,进行数字相加。(2) 数字减字符串,字符串转成数字。如果字符串不是纯数字就会转成 NaN。字符串减数字也一样。两个字符串相减也先转成数字。(3) 乘,除,大于,小于跟减的转换也是一样。(4) 无关 == 的隐式转换
a.undefined 等于 null
b. 字符串和数字比拟时,字符串转数字
c. 数字和布尔比拟时,布尔转数字
d. 字符串和布尔比拟时,两者转数字
2.2.2 援用类型的转换
(1) 如果 PreferredType 被标记为 Number,则会进行上面的操作流程来转换输出的值。a. 如果输出的值曾经是一个原始值,则间接返回它
b. 否则,如果输出的值是一个对象,则调用该对象的 valueOf() 办法, 如果 valueOf() 办法的返回值是一个原始值,则返回这个原始值。c. 否则,调用这个对象的 toString() 办法,如果 toString() 办法返回的是一个原始值,则返回这个原始值。d. 否则,抛出 TypeError 异样。(2) 如果 PreferredType 被标记为 String,则会进行上面的操作流程来转换输出的值
a. 如果输出的值曾经是一个原始值,则间接返回它
b. 否则,调用这个对象的 toString() 办法,如果 toString() 办法返回的是一个原始值,则返回这个原始值。c. 否则,如果输出的值是一个对象,则调用该对象的 valueOf() 办法, 如果 valueOf() 办法的返回值是一个原始值,则返回这个原始值。d. 否则,抛出 TypeError 异样。留神:PreferredType 的值会依照这样的规定来主动设置:a. 该对象为 Date 类型,则 PreferredType 被设置为 String
b. 否则,PreferredType 被设置为 Number
2.2.3 冒泡排序
// 冒泡排序
//1、比拟相邻的两个元素,如果前一个比后一个大,则替换地位。//2、比拟完第一轮的时候,最初一个元素是最大的元素。//3、这时候最初一个元素是最大的,所以最初一个元素就不须要参加比拟大小。function bubbleSort(arr) {
var len = arr.length;
// 外层管制循环多少趟
for (var i = 0; i < len-1; i++) {
// 内层管制每一趟的循环次数
for (var j = 0; j < len - 1 - i; j++) {
// 相邻元素两两比照,元素替换,大的元素替换到前面
if (arr[j] > arr[j + 1]) {var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
// 举个数组
var arr = [20,18,27,19,35];
// 应用函数
bubbleSort(arr)
2.2.4 break 和 continue 的区别
(1) 当执行 brea 后,会立刻跳出循环体
(2) 当执行 continue 时,不会跳出循环,而是立刻完结以后循环,进入下一次循环。
3. 函数
3.1 函数的作用
(1) 性能的封装
(2) 间接调用
(3) 代码复用率进步
3.2 函数申明
(1) 函数申明
function 函数名 (形参列表){// 函数体}
(2) 函数表达式
var 函数名 = function(形参列表){// 函数体}
这种模式看起来像惯例的变量赋值,先创立一个匿名函数,而后赋值给变量函数名。咱们晓得在 JS 中如果要想应用一个变量,必须先给这个变量赋值,所以函数表达式也不例外,在调用之前,必须先给它赋值。否则会报错。
3.3 函数外部属性
(1)arguments
a. 函数的参数在函数外部是应用一个类数组对象来示意的。这个类数组对象就是 arguments。b.arguments 是一个类数组对象,蕴含着传入函数中的所有参数。arguments 主要用途是保留函数参数,然而这个对象还有一个名为 callee 的属性,该属性是一个指针,指向领有这个 arguments 对象的函数
c.arguments 保留真正的实参
(2)this 面向对象语言中 this 示意以后对象的一个援用。a. 在办法中,this 示意该办法所属的对象。b. 如果独自应用,this 示意全局对象。c. 在函数中,this 示意全局对象。d. 在事件中,this 示意接管事件的元素。e. 在显式函数绑定时,咱们能够本人决定 this 的指向
3.4 IIFE 自执行函数
(1)IIFE:意为立刻调用的函数表达式,也就是说,申明函数的同时立刻调用这个函数
(2) 作用
a. 页面加载实现后只执行一次的设置函数。b. 将设置函数中的变量包裹在部分作用域中,不会泄露成全局变量。(3) 函数的申明和 IIFE 的区别
在函数的申明中,咱们首先看到的是 function 关键字,而 IIFE 咱们首先看到的是右边的(。也就是说,应用一对()将函数的申明括起来,使得 JS 编译器不再认为这是一个函数申明,而是一个 IIFE,即须要立即执行申明的函数。两者达到的目标是雷同的,都是申明了一个函数并且随后调用函数 foo。(4)IIFE 的写法
a. 对返回后果不进行解决
(function( 形参){函数体内容})(实参);
b. 对返回后果不进行解决
(function( 形参){函数体内容}(实参));
c. 返回的是一个布尔值,而后进行取反
!function(形参){函数体内容}(实参)
d. 对于数字返回的是原来的后果,非数字返回 NaN
+function(形参){函数体内容}(实参)
e. 对于数字返回的是正负符号相同,非数字返回 NaN
-function(形参){函数体内容}(实参)
f. 对于数字返回的是正负符号相同再减 1,非数字返回 -1
~function(形参){函数体内容}(实参)
g. 返回的后果是 undefined
void function(形参){函数体内容}(实参)
(5) 案列 - 经典面试题 -IIFE
for (var i = 0; i < 6; i++) {function output() {console.log(i); // 为什么输入的是 6,而不是 0,1,2,3,4,5
// 因为输入的 i 是全局作用域的,当循环完结后 i 的值是 6,所以输入的 i 就是 6。}
}
output()
for (var i = 0; i < 6; i++) {(function (j) {console.log(j); //0,1,2,3,4,5
})(i)
// 因为 JS 中调用函数传递参数都是值传递,所以当立刻执行函数执行时,首先会把参数 i 的值复制一份,而后再创立函数作用域来执行函数,循环 5 次就会创立 5 个作用域,所以每个输入拜访的都是不同作用域的 i 的值。}
(6) 为什么须要 IIFE?IIFE 的呈现是为了补救 JS(ES5) 在作用域方面的缺点:JS 只有全局作用域(global scope)、函数作用域(function scope),从 ES6 开始才有块级作用域(block scope)(7) 回调函数的作用
回调函数个别都用在耗时操作下面:因为主函数不必期待回调函数执行完,能够接着执行本人的代码。比方 ajax 申请,比方解决文件等。(8) 什么是闭包?闭包就是指有权拜访另一个函数作用域中的变量的函数
(9) 闭包的生成有三个必要条件
a. 函数嵌套函数
b. 外部函数援用了内部函数中的数据(属性、函数)c. 参数和变量不会被回收
(10) 闭包的用处
a. 能够读取函数外部的变量
b. 让这些变量的值始终保持在内存中。(11) 应用闭包的毛病
a. 因为闭包会使得函数中的变量都被保留在内存中,内存耗费很大,所以不能滥用闭包,否则会造成网页的性能问题
b. 闭包会在父函数内部,扭转父函数外部变量的值, 当父级的变量对象被批改时,所有子函数都受到影响
4. 数组
4.1 数组的个性
(1) 每一项都能够保留任何类型的数据。(2) 数组的大小是能够动静调整。(3) 数组的 length 属性:可读可写,能够通过设置 length 的值从数组的开端移除项或向数组中增加新项
4.2 数组的创立
(1) 字面量创立数组
由一对包含元素的方括号 "[]" 示意,元素之间以逗号 "," 隔开
var arr = [12,name,true,"larry",{},function(){},[],null];
(2) 通过 Array 构造函数来创立数组
var names = new Array();
var names = new Array('terry','robin')
4.3 数组拜访
拜访数组元素 数组变量名 [索引]
通过索引拜访数组,数组的索引从 0 开始,数组的索引超过数组长度会拜访到 undefined 值而不会报错。数组的长度通过 length 属性获取
a) [index] 间接拜访, 索引能够超过索引范畴,只不过拜访的值为 undefined
b) length-1=Max(index)
c) length+N 或 length-N 开拓新的内存空间 或 数组元素的删除
4.4 数组 API
4.4.1 数组序列化
(1) toString() 在默认状况下都会以逗号分隔字符串的模式返回数组项
var arr = [1,5,2,8,10,{a:1}];
console.log(arr.toString());//”1,5,2,8,10,[object Object]”(2)join() 应用指定的字符串用来分隔数组字符串
var arr = [1,5,2,8,10,{a:1}];
console.log(arr.join("-"));//”1-5-2-8-10-[object Object]”
4.4.2 构造函数的办法
(1) Array.isArray() 用来判断某个变量是否是一个数组对象
(2) Array.from() 从类数组对象或者可迭代对象中创立一个新的数组实例。(3) Array.of() 依据一组参数来创立新的数组实例,反对任意的参数数量和类型。
4.4.3 栈与队列办法
(1) Array.prototype.push() push() 办法可向数组的开端增加一个或多个元素,并返回新的长度。(2) Array.prototype.pop() pop() 办法用于删除数组的最初一个元素并返回删除的元素。(3) Array.prototype.shift() shift() 办法用于把数组的第一个元素从其中删除,并返回第一个元素的值。(4) Array.prototype.unshift() unshift() 办法可向数组的结尾增加一个或更多元素,并返回新的长度。
4.4.4 排序办法
(1) Array.prototype.reverse() reverse() 办法用于颠倒数组中元素的程序。(2) Array.prototype.sort() sort() 办法用于对数组的元素进行排序 如果调用该办法时没有应用参数,将按字母程序(Ascall 编码)
4.4.5 操作方法
(1) Array.prototype.concat() concat() 办法用于连贯两个或多个数组
(2) Array.prototype.slice() slice() 办法可提取字符串的某个局部,并以新的字符串返回被提取的局部
(3) Array.prototype.splice() splice() 办法用于增加或删除数组中的元素。
4.4.6 地位办法
(1) Array.prototype.indexOf() indexOf() 办法可返回数组中某个指定的元素地位。(2) Array.prototype.lastIndexOf() lastIndexOf() 办法可返回一个指定的元素在数组中最初呈现的地位,从该字符串的前面向前查找。
4.4.7 迭代办法
(1) Array.prototype.every()
every() 办法用于检测数组所有元素是否都合乎指定条件(通过函数提供)。every() 办法应用指定函数检测数组中的所有元素:- 如果数组中检测到有一个元素不满足,则整个表达式返回 false,且残余的元素不会再进行检测。- 如果所有元素都满足条件,则返回 true。(2) Array.prototype.some()
some() 办法用于检测数组中的元素是否满足指定条件(函数提供)。some() 办法会顺次执行数组的每个元素:- 如果有一个元素满足条件,则表达式返回 *true* , 残余的元素不会再执行检测。- 如果没有满足条件的元素,则返回 false。(3) Array.prototype.filter()
filter() 办法创立一个新的数组,新数组中的元素是通过查看指定数组中符合条件的所有元素。(4)Array.prototype.map()
map() 办法返回一个新数组,数组中的元素为原始数组元素调用函数解决后的值。(5) Array.prototype.forEach()
forEach() 办法用于调用数组的每个元素,并将元素传递给回调函数。
正文完
发表至: javascript
2021-09-02