浏览器
-
webkit内核(V8引擎)
- 谷歌 Chrome
- Safari
- Opera >= V14
- 国产浏览器
- 手机浏览器
- 。。。
-
Gecko
- 火狐Firefox
-
Presto
- Opera < V14
-
Trident
- IE
- IE EDGE开始使用双内核(其中包含Chromemium)
谷歌控制台(F12)
- Elements:查看结构样式,可以修改这些内容
- Console:查看输出结果和报错信息,用于js调试
- Sources:查看项目源码
- Network:查看当前网站所有资源的请求信息(包括和服务器传输的HTTP报文信息)、加载时间等(根据加载时间可以进行项目优化)
- Application:查看当前网站的数据存储和资源文件(抠图片等)
JS做看作客户端语言
按照相关js语法,去操作页面元素,有时还要操作浏览器里面的一些功能
- ECMAScript3/5/6…:js的语法规范(变量、数据类型。操作语句等等)
- DOM(document object model):文档对象模型,提供一些js的属性和方法,用来操作页面中的DOM元素
- BOM(browser object model):浏览器对象模型,提供一些js的属性和方法,用来操作浏览器的
JS中的变量(variable–变量)
变量:可变的量,在编程语言中,变量其实就是一个名字,用来存储和代表不同值的东西
//ES3
var a = 3;
a = 13;
console.log(a); //输出的是a代表的值13
// ES6
let b = 100;
b = 200;
const c = 1000;
c = 2000; //报错:const创建的变量,存储的值不能被修改(可以理解为叫做常量)
// 创建函数也相当于在创建变量
function fn(){}
// 创建类也相当于创建变量
class A{}
// ES6的模块导入
import B from './B.js';
// Symbol创建唯一值
let n = Symbol(100);
let m = Symbol(100);
n == n //==> false,这就是唯一值
JS中的命名规范
- 严格区分大小写
let Test = 100;
console.log(test);//无法输出,因为命名不一样(大小写)
- 使用数字、字母、下划线(_)、$;数字不能作为开头
let $box; //一般用JQuery获取的以$开头
let _box; //一般公共变量(全局变量)都是以_开头
let 1box; //不可以,但可以box1
- 使用驼峰命名法:首字母小写,其余每一个有意义单词的首字母都要大写(命名尽可能语义化明显,使用英文单词)
let studentIIformation;
let studentInfo;
// 常用的缩写:add/insert/create/new(新增)、update(修改)、delete/del/remove/rm(删除)、sel/select/query/get(查询)、info(信息)...
// 不正确写法:中文拼音,中文拼音与英文结合
- 不能使用关键字和保留字
// 当下有特殊含义的关键字,文莱可能会成为关键字的叫做保留字
// var let const function ...
// ==>代码强迫症(代码洁癖):良好的编程习惯,极客精神
JS中常用的数据类型
- 基本数据类型
- 数字 number:==>常规数字和NaN
- 字符串 string:==>所有用单引号、双引号、反引号(``)包起来的都是字符串
- 布尔 boolean:==>true/false
- 空对象指针 null
- 未定义 undefined
- 引用数据类型
- 对象数据类型 object
- {} 普通对象
- [] 数组对象
- /^$/ 正则对象
- /1?(\d|([1-9]\d+))(.\d+)?$/ ===> 验证是否为有效数字的正则表达式
- Math 数学函数对象
- 日期对象
- 类数组对象
- …
- 函数数据类型 function
- 对象数据类型 object
number数字类型
包含:常规数字、NaN
NaN
not a number: 不是一个数,但它隶属于数字类型
NaN和任何值(包括自己)都不相等:NaN != NaN
isNaN
检测一个值是否为有效数字,如果不是有效数字返回true,反之是有效数字返回false
在使用isNaN进行检测的时候,首先会验证检测的值是否是数字类型,如果不是,先基于Number()这个方法,把值转换为数字类型,然后检测
console.log(isNaN('10')); // => false
/* Number('10') ==> 10
isNaN(10) ==> false */
console.log(isNaN('AA')); // => true
/* Number('AA') ==> NaN
isNaN(10) ==> true */
把其他类型值转化为数字类型
- Number([val])
字符串转换为数字:只要字符串中包含任意一个非有效数字字符(第一个点除外)结果都是NaN,空字符串会变成数字0
引用数据类型转化为数字:先把它基于toString()方法转换为字符串,然后再转换为数字
// 字符串转换为数字
console.log(Number('12.5')); // => 12.5
console.log(Number('12.5px'),Number('12.5.5'); // => NaN NaN
console.log(Number('')); // => 0
// 布尔转换为数字
console.log(Number(true)); // => 1
console.log(Number(false)); // => 0
// null --> 0, undefined --> NaN
console.log(Number(null)); // => 0
console.log(Number(undefined)); // => NaN
// 普通对象
// {}/{xxx:'xxx'} .toString() => "[object Object]" => NaN
console.log(Number({name:'10'})); // => NaN
console.log(Number({})); // => NaN
// 数组对象
// [].toString() => '' => 0
console.log(Number([])); // => 0
// [12].toString() => '12' => 12
console.log(Number([12])); // => 12
// [12,1].toString() => '12,1' => NaN
console.log(Number([12,1])); // => NaN
- parseInt([val])
- parseFloat([val],[进制])
它们也是转换为数字的方法,对于字符串来说,他是从左到右依次查找有效数字字符,知道遇到非有效数字字符,停止查找(不管后面是否含有数字),把找到的当做数字返回
let str = '12.5px';
console.log(Number(str)); // => NaN
console.log(parseInt(str)); // => 12
console.log(paeseFloat(str)); // => 12.5
console.log(paeseFloat('width:12.5px')); // => NaN
- ==进行比较的时候,可能出现把其他类型值转换为数字
cosole.log('10' == 10) ==> true
string字符串类型
所有用单引号、双引号、反引号(ES6模板字符串)包起来的都是字符串
把其他类型值转换为字符串
- [val].toString()
null和undefined是禁止直接toString的
普通对象.toString()的结果是"[object Object]";因为Object.prototype.toString方法不是转换为字符串的,而是用来检测数据类型的
- 字符串拼接
四则运算中,除加法(+)之外,其余都是数学计算,只有加法可能存在字符串拼接(一旦遇到字符串,则不是数学运算,而是字符串拼接)
console.log('10' + 10); // '1010'
console.log('10' - 10); // 0
console.log('10px' - 10); // NaN
//
let a = 10 + null + true + [] + undefined + '我哦' + null + [] + 10 +false;
console.log(a); // 11undefined我哦null10false
/*
10 + null --> 10 + 0 --> 10
10 + true --> 10 + 1 -- > 11
11 + [] --> 11 + '' --> '11'
'11' + undefined --> '11undefined'
...
11undefined我哦null10false */
boolean布尔数据类型
只有两个值 true/false
把其他类型值转化为布尔类型
只有0、NaN、’’、null、undefined五个值转换为false,其余都转换为true(而且没有任何特殊情况)
- Boolean([val])
- !/!!
- !:取反,先转为布尔,然后取反
- !!:取反再取反,只相当于转换为布尔,相当于Boolean()
- 条件判断
如果条件只是一个值,不是==/===/!=/>=/>=等这些比较,要先把这个值先转换为布尔类型,然后验真真假
null / undefined
null 和 undefined都代表没有;null代表意料之中(一般都是开始不知道,然后手动先设置null),undefined代表意料之外(不是我能决定的)
let num = null 和 let num = 0;一般最好用null作为初始的空值,因为0不是空值,它在栈内存中有自己的存储空间(占了位置)。let num;创建一个变量没有赋值,默认值是undefined
object对象数据类型 - 普通类型
{[key]:[value],…} 任何一个对象都是由零到多组键值对(属性名:属性值)组成的(并且不能重复)
获取属性值:对象.属性名,对象[ 属性名];属性名不存在则默认的属性值是undefined;如果属性值是数字,则不能使用点的方式获取属性值
设置属性名属性值:. 与 []
删除属性
- 真删除:彻底删除属性
- 设置为空(null)
- 假删除:属性还在,值为空
- delete
数组是特殊的对象数据类型:属性名是是默认生成的数字,从零开始递增,我们也叫做 ‘索引’ => 从零开始,连续递增,代表每一项位置的数字属性名。天生默认一个属性名 length,存储数组的长度
数据类型(堆栈底层机制)
浏览器想要执行js代码
- 从电脑内存中分配出一块内存,用来执行代码(栈内存 => Stack)
- 浏览器分配一个主线程用来自上而下执行js代码
JS中的数据类型检测
- typeof[val]:用来检测数据类型的运算符
- 首先是个字符串
- 字符串中包含对应的类型
- 局限性
- typeof null => “object”,但null并不是对象而是空对象指针
- 基于typeof无法细分当前对象是普通对象还是数组对象等,因为只要是对象数据类型,返回的结果都是"object"
console.log(typeof typeof typeof []);
/* typeof [] ==> "object
typeof "object" ==> "string"
只要两个及两个以上typeof同时检测,最后结果必然是"string" */
- instanceof:用来检测当前实例是否属于某个类
- constructor:基于构造函数检测数据类型(也是基于类的方式)
- Object.prototype.toString.call():检测数据类型最好的方法
JS中的操作语句:判断、循环
判断
成立于不成立 。。。。
- if/else if/else
if(条件1) {
// 条件1成立执行
} else if(条件2) {
// 条件2成立执行
} else{
// 以上条件都不成立
}
- 三元运算符(条件 ? 成立 : 不成立)
- 如果处理事情较多,可用括号包起来,每一件事情用逗号分隔
- 如果不需要处理事情,可以使用null/undefined(void(0);)占位
- switch case
- case 用的是 === 绝对等号
- 不加break,当前条件成立执行完成后,后面条件不论是否成立都要执行,直到遇到break为止。不加break可以实现变量在某些值的情况下做相同的事情。
- == 与 === 相等于绝对相等(数据类型与值)
循环
- for循环
- continue:结束当前这轮循环,continue后面代码不在执行,继续下一轮循环
- break:强制结束整个循环,break后面也不在执行
- for in 循环:for(var key in obj){key,obj[key]}
- 用来循环遍历对象中的键值对(continue和break同样适用)
- for in在遍历的时候,优先循环数字属性名(从小到大)
- for of 循环
- while 循环
- do while循环
函数
函数就是一个方法或者一个功能体,函数就是把实现某个功能的代码放到一起进行封装,以后想要操作实现这个功能,只需要把函数执行即可 => “封装”:减少页面中的冗余代码,提高代码重复使用率(低耦合高内)
- 创建函数
- 形参
- 返回值
- 执行函数
- 实参
- arguments
- 函数内置的实参集合
- 类数组集合,集合中存储着所有函数执行时,传递的实参信息
- 不论是否设置形参,是否传递实参,arguments都存在
- arguments·callee:存储当前函数本身,一般不用,严格模式下禁止使用
- 函数底层机制
- 创建函数,开辟的堆内存中存储的是函数体中的代码,但是是按照字符串存储的
- 每次函数执行的目的都是把函数体中的代码(先从字符串变为代码)执行 => 形成一个全新的私有栈内存
- 函数的每次执行都会创建一个私有栈内存(内存的释放和溢出)
- …
1.实参没传值,形参默认是undefined
创建函数
function [函数名]([形参变量1],...){
// 函数体:基于JS完成需要实现的功能
return [处理后的结果]
}
//执行函数
[函数名]([实参1],...)
匿名函数
匿名函数之函数表达式:把一个匿名函数本身作为值赋值给其他东西,这一种函数不是手动触发执行,而是靠其他程序驱动触发执行(eg:触发某个事件的时候把他执行)
document.body.onclick = function () {}
setTimeout(function(){},1000) //设置定时器,1000ms后执行匿名函数
匿名函数之自执行函数(立即执行函数):创建完一个匿名函数,加一个小括号执行
(functio(n){
// n => 100
})(100);
箭头函数
+ 箭头函数没有arguments,但可以使用剩余运算符获取到传递实参的集合(是数组)
+ let sum = (...arg) = eval(arg.join('+'));
function sum(n,m) {
return n + m;
}
let sum = (n, m) => {
return n + m;
}
let sum = (n,m) => n + m;
// 形参默认值
let sum = (n = 0,m = 0) => n + m;
Math
Math不是一个函数,是一个对象,对象中存储了很多操作数字的属性方法,所以被称为数学函数
Math中常用的属性和方法
1.Math.abs([number value]):绝对值
2.Math.ceil/floor():向上取整。向下取整
3.Math.round():四舍五入;正数中,.5属于入;负数中,.5属于舍
4.Math.max/min([val1],[val2],…):最大值、最小值
5.Math.sqrt/pow():开平方/多少次幂。负数无法开平方(NaN);Math.pow(2,10)==>1024
6.Math.random():获取01之间的随机小数。获取[nm]之间的随机数:Math.round(Math.random()*(m-n)+n)
数组
数组是一个对象,以数字为key,有length属性
数组中常用的方法
1.实现数组增删改的方法(原数组会改变)
`push:向数组末尾增加内容(多个任意类型,返回数组新长度)
`unshift:数组开始位置增加内容
基于原生ES6展开运算符,把原有的数组克隆一份,在新数组中创建第一项,其余的内容使用原始数组中的信息,这也算实现了翔开始追加的效果:arry = [100, ...arry]
`shift:删除第一项,返回删除的元素
基于原生JS中的delete的话,删除后数组length不会改变破坏了数组的结构,避免折磨做
`pop:删除最后一项,数组返回undefined
`splice:实现数组的增删改
array.splice(start,[deletecount])
1. 从索引start开始删除deletecount个元素,没有则是start后的全部删除;返回删除的数组;
2. start若为负数这是选取倒数;
3. deletecount大于等于.length-start或者被省略,则是删除后面全部;
4. 如果 deleteCount 是 0 或者负数,则不移除元素
删除最后一项:arry.splice(arry.length -1)
删除第一项:arry.splice(0,1)
基于这种方法可以清空一个数组并且把原数组中的内容已新数组存储起来(arry.splice(0)),类似于克隆
数组的查询和拼接(原数组不会改变)
`slice:实现数组的查询
array.slice(n,[m])
1. 从索引n开始,找到索引为m的地方(不包含m)
2. 把找到的内容以一个新数组的形式返回
3. m不写,找到末尾
4.res = ary.slice(0):数组的克隆,参数0不写也可;浅拷贝(浅克隆),如果是对象,则是拷贝对象的引用地址,两数组指向同一个引用地址,基本数据类型则拷贝值,互不影响
5. n大于原数组长度,则返回空数组;m大于原数组长度,找到末尾;n/m为负数则表示倒数第几个
`concat:用于合并两个或多个数组,返回一个新数组。
newArry = oldArry.concat(value1,value2,...),浅拷贝
数组转化为字符串(原数组不变)
`toString:把数组转化为字符串
arry.toString(),每一项用逗号分隔
`join:-
arry.join(字符串分隔符),不指定分隔符用,
检测数组中是否包含某一项
`indexOf/lastIndexOf:检测当前项在数组中第一次/最后一次出现位置的索引值;如果没有,则返回-1(在IE6~8中不兼容)
`includes:判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false;ES6新提供
它们都是 严格相等比较(===),比较字符串和字符时是区分大小写
数组的排序/排列
`reverse:将数组中元素的位置颠倒,并返回该数组,会改变原数组
`sort:实现数组的排序
1. 不传参数,默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
2. 可以传递一个函数,按返回值排序;<0,a<b;>0,a>b;=0不变
数组遍历
`foreach:遍历数组中的每一项
数组去重
+ 循环(for,foreach)使用includes(indexOf)方法
+ 双重循环,消除重复,注意数组塌陷问题
+ 基于对象,用对象存储,键值对都是数组元素(undefined)
+ 数组去重:用splice注意性能;可用最后一项替换重复数组(arr[i] = arr[arr.length-1];arr.length--;i--)
字符串中常用方法
+ charAt()
+ charCodeAt(),与String.fromCharCode() 相反
+ substr(start,length):start等于或大于字符串长度,length为0或负数,返回空字符串;start为负数,倒数的;start为负数且大于长度,则从0开始
+ substring(start,end)
1. start=end,返回一个空字符串。
2. 任一参数小于0 或为 NaN,则被当作 0。
3. 任一参数大于length,则被当作length。
4. start > end,反转调换效果一样
+ slice(start,end(不包括)):负数,倒数的
+ indexOf/lastIndexOf/includes
+ toUpperCase/toLowerCase:字符的大小写转化
-|-|-补充
-
集合与数组类似,以数字索引为属性名,有length长度,但不是数组,是类数组
-
JS中DOM元素对象中的classList(得到一个DOMTokenList 对象),获取元素的类名,有length属性,有add(),remove(),contains(),toggle(),item(索引)方法
-
dislay:flex ==> 容器中的子元素默认在容器主轴(X轴)水平靠左排列
-
浏览器常用的输出方式
- console.log/dir/table…在控制台输出
- console.dir:获取对象的详细键值对信息
- .table:把一个多维JSON数组在控制台按照表格的方式呈现出来
- 浏览器窗口弹窗 alert/confirm/prompt
- alert:三种都要经过toString转换为字符串
- confirm:确定和取消,选择型弹框
- prompt :多了输入框
- document.write:在页面中写入信息,输出的结果都是字符串
- console.log/dir/table…在控制台输出
-
let i = ‘10’;
i=1+1 => ‘10’+1 => ‘101’
i+=1 => ‘101’
i++ => i=11和以上两种不完全一样,他是村催的数学运算
- i++与++i都是数学运算的累加1,它们的运算顺序不一样,i=1
- 5+(i++) => 5+i=6,i再加1(i=2)
- 5+(++i) => i+1=2,5+i=7
5+4+4+3-2+4+4-2
-
数组塌陷问题:数组删除时会出现问题
- 当数组删除时,将i–
- 将数组倒着循环遍历
-
基于splice实现删除,当数据量大时,影响性能
-
/* * unique:实现数组去重方法 * @params * arr [Array] 要去重的数组 * @return * [Array] 去重后的数组 */ function unique(){}
+- ↩︎