运行在客户端的脚本语言,脚本语言不需要编译;
功能:可以处理事件点击、输入等;改变HTML内容、位置和样式等;处理http请求、各种业务逻辑的执行等。
浏览器本身不会执行js代码,是通过内置的JavaScript引擎(解释器)来执行,逐行解释然后由计算机去执行;
- 将js放在body的最后面,可以避免资源阻塞,同时使静态的html页面迅速显示。
# 组成
由3部分组成:语法(ECMAScript)、页面文档对象模型(DOM)、浏览器对象模型(BOM)
3种方式:
行内式 如onclick
内嵌式 在
<script></script>
标签里面写js语法外嵌式
<script src="my.js"></script>
js文件返回的是个函数调用结果
# JavaScript语法
# 常用语句
alert(msg); 浏览器弹出警示窗;
console.log(msg); 控制台打印;
prompt(info); 浏览器弹出输入框,用户可以输入,方法返回用户输入的字符串类型数据;
JSON.stringify(value); JavaScript对象转换为JSON字符串
JSON.parse(value); JSON字符串转为JavaScript对象
${param} $用于获取参数param的值,拼接在字符串中
url: www.baidu.com/abc/${current}/${limit}
# 变量
声明变量 var
只声明,不赋值,undefined
不声明,只赋值,也可以会变成全局变量
驼峰命名
变量的数据类型是弱类型/动态语言,只有在执行的时候根据右边的值才能确定是什么类型的数据
数据类型是可变的
简单数据类型:Number(0)、String("")、Boolean(false)、Undefined(undefined)、Null(null)
复杂数据类型:Object
数字前面加0,则表示八进制
数字前面加0x,则表示十六进制
数字的最大值:Number.MAX_VALUE
数字的最小值:Number.MIN_VALUE
非数值:NaN
isNaN(vaq); 判断是非数字,vaq不是数字,返回true
字符串:单引号或双引号;建议使用单引号
vaq.length; 获取字符串的长度
Boolean中的true参与算法运算可以当1来算,false当做0处理
undefined+1结果为 NaN
null+1结果为1
# typeof用法
var vaq = 'VAQ';
console.log(typeof vaq); // string
控制台中打印的紫色字体是数字、黑色是字符串、蓝色是boolean
# 数据类型转换
# 其他类型转为字符串
- toString();
- String(VAQ);
- VAQ+''; //最常用
# 其他转为数值
- parseInt(VAQ); //转成整型 可以取以数字开头的字符串,只得到数字 (输入框默认会是字符串,可用此方法转为数字)
- parseFloat(VAQ); //转成浮点数类型 可以取以数字开头的字符串,只得到数字
- Number(VAQ); 转成数值型
- 减号、乘号、除号这三种可以隐式转换
# 其他转为布尔
Boolean(VAQ); // NaN、null、undefined、''、0 这五个会转换成false,其他都会转成true
浮点数做运算会丢失精度
递增/减 必须和变量搭配 (++、--)
前置递增:++n 先加1,再返回值
后置递增:n++ 先返回原值,再加1
赋值运算符: = 直接赋值;
+=、-= 加、减一个数后再赋值;
*=、/=、%= 乘、除、取模后再赋值
逻辑与&& 比 逻辑或|| 优先级高
switch中的表达式和case是用全等(===)的方式比较的
循环的三种方式:for、while、do while
# 数组
创建数组
var arr1 = new Array();
var arr2 = [];
数组中可以存储任意类型的元素
获取数组元素 arr[0]
遍历数组 for循环
数组长度 arr.length
修改数组长度 arr.length = num;
追加数组元素
arr = [1,2,3];
arr[3] = 4;
# 函数
声明函数
function funName(){ }
函数形参不传值,默认是undefined
函数没有return,则返回undefined
所有的函数都内置了一个arguments对象,它存储了传递的所有实参
arguments是个伪数组;伪数组:具有长度.length;有索引;没有正真数组的方法pop()、push()等;
函数声明方式:
1. function funName(){}; // 命名函数
2. var fun = function(){}; //匿名函数
作用域:
全局作用域:<script>
标签,或一个单独是js文件
局部作用域:在函数的内部
# js预解析
JavaScript会先预解析代码,然后再执行
js引擎会将所有的var变量和function提到当前作用域的最前面
变量预解析:只提升变量,不提升赋值
函数预解析:只提升函数声明,不调用函数
# 对象
==创建==:
- 字面量创建 { }
var obj = {
name: 'VAQ',
age: 18,
sayHi: function( ){
console.log('hi~')
}
}
调用属性:
obj.name // 方式一
obj['name'] // 方式二
调用方法:
obj.sayHi( )
- new Object( ) 创建
var obj = new Object( );
obj.name = 'VAQ';
obj.age = 18;
obj.sayHi = function( ){
console.log('hi~');
}
- 构造函数创建
function Star(name, age ){
this.name = name;
this.age = age;
}
var obj = new Star('VAQ',18);
new关键字执行流程:构造函数先在内存中创建一个空的对象,this指向空对象,执行构造函数的代码,给空对象添加属性和方法,返回对象
Object常用方法
Object.assign(target,source); //将source的属性赋值给target,返回target(ES6)
Object.create(target); //创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
Object.defineProperty(target,prop,descriptor); //在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
Object.getOwnPropertyNames(target); //返回指定对象的所有属性名组成的数组
obj.hasOwnProperty(prop); //判断是否有指定的属性
Object.is(target,source); //判断两个值是否为同一个值(ES6)
Object.keys(obj); //返回包括所有key(obj是数组时返回索引)的Array数组wd
Object.values(obj); //返回包括所有value的Array数组
# Object.defineProperty(target,prop,descriptor);
let number = 18;
let person = {
name: 'vaq',
sex: '男'
}
Object.defineProperty(person,'age',{
value: 18,
enumerable: true, // 控制属性是否可以枚举,Object.keys(),默认为false
writable: true, // 控制属性是否可以被修改,默认为false
configurable: true // 控制属性是否可以被删除,默认为false,
get(){
console.log('有人读取了age属性');
return number
},
set(value){
console.log('有人修改了age属性,且值是',value);
number = value
}
})
# for in 遍历对象
for(var key in obj){
console.log(key); // 属性名
console.log(obj[key]); // 属性值
}
# JavaScript的对象
内置对象、浏览器对象、自定义对象
# 内置对象
# Math对象
Math.PI 圆周率 Math.max(1,99,3); 最大值 Math.random(); 随机数
# Date日期对象
通过构造函数来创建
var date = new Date();
data.getFullYear( );
# Array数组对象
var arr1 = new Array(3); // 长度为3的空数组
var arr2 = new Array(1,2,3); //等价于 [1,2,3]
检测是否为数组:
console.log(arr instanceof Array);
console.log(Array.isArray(arr));
常用方法:
push(参数1...); // 末尾添加一个或多个元素;返回的是新数组的长度
pop( ); //删除最后一个元素;; 返回的是删除的那个元素
unshift(参数1...); //向数组的开头添加一个或多个元素;返回的是新数组的长度
shift( ); //删除第一个元素; 返回的是删除的那个元素
reverse( ); // 颠倒顺序;
sort( ); // 排序 1,13,2,34,5,6
var arr = ['red','green','blue','red']
arr.indexOf('red'); //返回0;返回满足的第一个索引号;如果没有则返回-1
arr.lastIndexOf('red'); //返回3;返回满足的最后一个索引号;如果没有则返回-1
arr.toString( ); //转成字符串
arr.join( ); //转成字符串,以指定符号分隔,默认是逗号;
arr.join('。'); 结果为:red。green。blue。red
# 字符串对象
字符串不可变
var str = 'VAQ';
str.length //字符串长度
str.indexOf('Q',n); //根据字符返回位置,n表示起始位置,可以不写;找不到则返回-1
str.lastIndexOf('Q'); //从后面开始查找第一个匹配的位置
str.chatAt(index ); //返回指定索引号的字符
str.chatCodeAt(n); //返回指定索引号的字符的ASCLL码
str[index]; //与str.charAt(n)等效
str.concat(str1,str2...); //连接字符串,等效与(+),+更常用
str.substr(start,length); //从start位置开始,截取length个字符
str.slice(start,end); //截取[start,end)的字符串
str.substring(start,end); //和slice同效
str.replace(source,target); //把source替换成target
str.split('分隔符'); // 通过分隔符转换为数组
str.toUpperCase( ); //转换为大写
str.toLowerCase( ); //转换为小写
# 简单数据类型(基本类型、值类型)和复杂数据类型(引用类型)
值类型:string、number、boolean、undefined、null;存于栈中
引用类型:Object、Array、Date、Math等;存于堆中
# DOM页面文档对象模型
DOM树
- 文档:一个页面就是一个文档,document表示
- 元素:页面内所有的标签,element表示
- 节点:网页中所有内容都是结点,如标签、属性、文本、注释等,node表示
获取元素:
通过id获取:document.getElementById('id'); //返回对象
通过标签名获取:document.getElementsByTagName('tagName'); //返回的是伪数组
获取指定元素下指定标签名的元素?可以先获取父元素,再用父元素通过标签名获取
通过类名获取:document.getElementsByClassName('className');
document.querySelector('选择器'); //根据指定选择器返回第一个元素对象
document.querySelector('#id');
document.querySelector('tagName');
document.querySelector('.className');
document.querySelectorAll('选择器'); //根据指定选择器返回所有元素对象
获取html标签:
document.documentElement
获取body标签:
document.body
鼠标事件:
onclick 点击左键触发
onmouseover 经过时触发
onmouseout 离开时触发
onfocus 获得焦点时触发
onblur 失去焦点时触发
onmousemove 移动时触发
onmouseup 弹起时触发
onmousedown 按下时触发
修改普通标签的内容,不能修改input的内容;想修改input标签的内容时,修改其value
element.innerText
起始位置到终止位置的内容,不包括HTML标签,会去掉空格和换行
element.innerHTML
起始位置到终止位置的内容,包括HTML标签,同时保留空格和换行
img.src = '';
//就能重新给img标签下的src属性重新赋值
- 表单的属性操作:
var btn = document.querySelector('button');
btn.onclick = function(){
input.value = '被点击了';
input.disabled = true;
this.disabled = true; //this指事件函数的调用者,这里指btn
}
修改样式属性:
element.style
//行内样式操作,适合修改较少的样式element.className
//类名样式操作,可以更改当前元素的类,覆盖掉以前的;适合修改较多的样式
利用document可以操作这些表单属性:type、value、checked、selected、disabled
# DOM操作元素
# 操作元素内容
innerText、innerHTML
# 操作元素属性
src、href、title、alt等
# 获取属性的值
element.src //获取内置属性
element.src = '' //设置属性值
element.getAttribute('属性名'); //获取自定义属性 ,规定自定义属性都是data-开头的属性名
element.setAttribute('属性名','属性值'); //设置自定义属性值
element.removeAttribute('属性名'); //移除属性
# 操作表单元素属性
type、value、disabled等
# 操作元素样式属性
element.style、element.className
# 节点操作获取元素
js中万物皆是节点,至少包括nodeType节点类型、nodeName节点名称、nodeValue节点值;
元素节点nodeType=1,属性节点nodeType=2,文本节点nodeType=3(文字、空格、换行等),
# 获取父节点
<div class='color'>
<div class='red'> </div>
</div>
var node = document.querySelector(".red");
node.parentNode; //最近的上一节点,即class为color的节点
# 获取子节点
node.childNodes; //包含子节点,包括元素节点、文本节点
node.children; //只包括子元素节点;开发中常用
node.firstChild; //获取第一个子节点,包括元素节点、文本节点
node.lastChild; //获取最后一个子节点,包括元素节点、文本节点 等效于 node.children[node.children.length-1];
node.firstElementChild; //获取第一个子元素节点
node.lastElementChild; //获取最后一个子元素节点
# 获取兄弟节点
node.nextSibling; //获取下一个兄弟节点,包含元素节点、文本节点
node.previousSibling; //获取上一个兄弟节点,包含元素节点、文本节点
node.ElementSibling; //获取下一个兄弟元素节点
node.previousElementSibing; //获取上一个兄弟元素节点
没有时,返回null
# 创建节点、添加节点
var li = document.createElement('li'); //创建节点
var ul = document.querySelector('ul');
ul.appendChild(li); //在父节点的子节点最后追加子节点
ul.insertBefore(li,ul.children[0]); //在父节点的指定位置前插入节点
# 删除节点
node.removeChild(child); //删除父节点中的一个子节点
# 复制节点
node.cloneNode(); 或node.cloneNode(false); 只复制当前节点,不赋值其子节点
node.cloneNode(true); 深度复制,也复制其子节点
# 事件
DOM中所有的事件对象都是基于Event对象的,都可以访问Event对象的属性、方法
event.preventDefault();
如果事件可以取消,调用该方法就会将其取消
# 注册/绑定事件:给元素添加事件
- 传统注册方式 同一个元素同一个事件只能设置一个处理函数,后面的处理函数会将前面的函数覆盖掉
- onclick
- btn.onclick = function(){}
- 方法监听注册方式 addEventListener(); //同一个元素同一个事件可以注册多个监听器
<button> 这是个按钮</button>
var btns = document.querySelectorAll('button');
btns[0].addEventListener('click', function(){
alert('这是弹窗1');
});
btns[0].addEventListener('click',fn);
function fn(e){
alert('这是弹窗2');
}
这两个方法会依次执行
# 删除/解绑事件
传统方式
btn.onclick = null;
方法监听方式
removeEventListener('click',fn);
//fn是监听注册的函数
# DOM事件流
多个事件的传播过程
事件流的两个阶段:
- 捕获阶段:事件从document到父级再到子级依次执行
- 冒泡阶段(常用):事件从子级到父级别一直到DOM最顶层节点依次执行
btn.addEventListener('click',fn,true);
// true表示捕获阶段,false或空表示冒泡阶段
onblur、onfocus、onmouseenter、onmouseleave没有冒泡
- 事件对象
ul.addEventListener('click',function(e){
console.log(e);
e.stopPropagation(); // 阻止冒泡事件
}
e //表示当前事件的对象;
e.target //返回的是触发事件的对象,this返回的是绑定事件的对象
e.type //返回事件类型,如click、mouseover、mouseout
e.preventDefault() //阻止默认方法,如本来click点击,让其失效
e.stopPropagation(); // 阻止冒泡事件
- 事件委托 不给每个节点设置事件监听器,而是将事件监听器设置在其父节点上,通过冒泡原理影响设置所有的子节点
# BOM浏览器对象模型
浏览器窗口进行交互的对象,核心是window,window是浏览器的顶级对象,是全局对象
BOM包含了DOM
window.document
window.location
window.navigation
window.screen
window.history
- 窗口/页面加载事件
window.onload = function(){};
或
window.addEventListener('load', function(){});//当文档内容(包括图像、脚本文件、CSS文件等)完全加载完成后会触发该事件调用处理函数;
window.addEventListener('DOMContentLoaded',function(){}); 仅当DOM(不包括CSS、图片)加载完成后触发该函数
- 调整页面大小事件
全局作用域和普通函数中,this指window
window.onresize = function(){};
window.innerWidth //当前屏幕的宽度
window.setTimeout(调用函数,延迟毫秒数(可省略,默认为0));//定时器定时调用一次这个函数
window.clearTimeout(timeoutId);//停止定时器
window.setInterval(调用函数,延迟毫秒数(可省略,默认为0));//定时器定时无限循环调用多次这个函数
window.clearInterval(timeoutId);//停止定时器
异步任务 普通事件:click、resize等
资源加载:load、error等 定时器:setTimeout、setInterval等;
异步任务的相关回调函数会添加到任务队列中;
js会先执行执行栈中的同步任务,执行结束后再执行任务队列中的异步任务 事件循环:主线程不断重复获得任务、执行任务、再获取异步任务、执行任务......的机制location对象
location.href //获取或设置整个url
location.host //主机/域名
location.port //端口号
location.pathname //路径
location.search //返回参数
location.hash //返回锚点链接
location.assign('http://www.baidu.com'); //和href一样,跳转页面(重定向)记录历史,可以实现后退
location.replace('http://www.baidu.com'); //不记录历史,不可以后退
location.reload(); //重新加载页面,相当于F5
* navigator 包含浏览器的一些属性
navigator.userAgent 是客户机向服务器发送的user-agent头部的值
- history 与浏览器历史记录进行交互
history.back() //后退;
history.forward //前进;
history.go(参数) //前进或后退;参数是1则前进一个页面,是-1则后退一个页面,-2后退两个
# Others
# navigator.clipboard
剪切板功能
# import
js中的import的会最先执行
这三种方式都是可以的,因为引入router文件夹却没有指定文件时默认就会找index.js文件(Node.js的规范)
import router from './router'
import router from './router/index'
import router from './router/index.js'
# _proto_和prototype
_proto_是每个对象都有的属性,称为隐式原型,它指向了构造该对象的构造函数的原型,保证了实例能够访问在构造函数原型中定义的属性和方法(toString()、valueOf())
prototype,称为显示原型,函数是个特殊的对象,除了和其他对象一样有_proto_属性外,还有个特有的属性prototype,这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数
# 判空
if(!obj){
// 为null或者为空字符串,就会进来
}
# 获取json数据
params:{'age':18,'name':'VAQ'}
var age = params['age']