JavaScript基础
JavaScript:动态脚本语言
-
弱类型
-
动态类型
I/o:文档交流
由三部分组成:
-
ECMAScript(语言核心)
-
DOM (文档对象模型)
-
BOM (浏览器对象模型)
-
浏览器渲染 html 是从上到下的
- 一般来说,会将 script 放到 head 中,但是为了渲染速度,很多时候,会放到 body 的最后
- 如果 script 标签不闭合,会导致页面渲染出问题
在JS执行中都是单线程执行,所以代码的执行可以说是自上而下,如果前一段的代码出现问题,就会导致下一段代码无法执行,对于用户而言就是卡死现象,所以在JS执行机制引出了异步执行操作。
var x = 1; // 赋值
//在js中,number 表示一切数字,包括整数和浮点数。全都是 64 位。
//undefined表示未定义, null 表示为空
//boolean 表示布尔 只有true和false
1.1函数:就是 执行逻辑 的一种封装。
function mysum(a,b){}; mysum(1,2); // 往里写入参数,返回1,2
var abs = function(a,b){};
1.1.2预定义函数:
parseInt();将字符串转换成整数,无法解析则返回NaN
parseFloat();将字符串转换成浮点数,无法解析则返回NaN
eval(); 将字符串参数作为JavaScript代码执行
isNaN(); 判断指定内容是否为非数字,只有纯数字组成的返回false,否则返回true
例:isNaN(NaN); //true
isNaN(1122); /false
escape()函数的作用是将一些特殊字符转换成ASCII码
unescape()函数的作用是将ASCLL码转换成字符
1.1.3 回调函数
function mysum(a,b,f){ return f("出错了,")} //f是一个函数,用来表示出错时候的逻辑
//实现逻辑的分离
//一旦执行到return时,函数就执行完毕,并将结果返回。
1.1.4 递归函数
function rec(){
console.log("hello");
if(Math.random() > 0.999){
ruturn;
}
rec();
}
rec(); //它是计算机进行计算更加本质的一种行为
//它可以完全替换掉循环语句
//烧脑,不够直观
//烧内存,爆栈。没有递归做进一步优化,尾递归优化
//递归必须要有边界条件 !!!
1.1.5 箭头函数
x => x * x
//等价于
function (x) {
return x * x;
}
1.1.6 generator (生成器) : ES6引入的新的数据类型,可返回多次
function* foo(x){
yield x + 1;
yield x + 2;
return x + 3; //generator由function*定义
//还可以用yield返回多次
}
调用generator对象的方法:
1.不断调用generator对象的next()方法
var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: undefined, done: true}
//另外,generator可以把异步回调代码变成'同步'代码,要等AjAx以后才能知道
2.1 数据类型
2.1.1 JS中的5种原始数据类型:
- undefined, 未定义,尚未赋值
- null 空
- boolean 布尔类型
- number 数字(浮点型,包含小数点的实数)
- string 字符串
var a = a;
let a = 1; //优先使用 const,在数据需要修改的时候,使用 let,迫不得已 var
const a; //千万不能忘掉 var 的原理跟使用方式,因为面试需要
//const 赋值后,将不能再赋值,否则将报错
//将各种变量放入函数中,叫做闭包,提高安全
//当一个变量没有声明var,let,const类型时,它将会是一个全局变量,会产生调试的错误
2.1.2 在ES6中提出了变量定义的关键词:(let/const)
区别: 块级别的作用域
优先使用const,在数据需要修改的时候,使用let,迫不得已var
千万不能忘记var的原理跟使用方法,因为面试需要
3.1.1 词法作用域
即静态绑定
好处:
- 函数定义时绑定了某个变量,后面就不会发生变化
- 便于理解,便于调试,不容易出错
3.1.2 闭包
闭包的根源是词法作用域
主要目的:
- 为了保护变量,不被外部修改
- 为了使数据在内存中驻留
- (可能引发的内存泄漏)
var count = 1; //count是暴露在外的,可能被篡改,不安全
function Counter(){
let count = 1;
//使用闭包,保护count的安全
//能够确保count在函数调用之后会一直存在,不会被释放
}
3.1 window对象/杂项
3.1.1 window:浏览器窗口对象
3.1.1 arguments:它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数
function foo(x) {
console.log('x = ' + x); // 10
for (var i=0; i<arguments.length; i++) {
console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
}
}
foo(10, 20, 30); // 利用arguments 可以获得调用者传入的所有参数,即使函数不定义任何参数,还是可以拿到参数的值
//实际上arguments最常用于判断传入参数的个数。你可能会看到这样的写法:
function foo(a, b, c) {
if (arguments.length === 2) {
// 实际拿到的参数是a和b,c为undefined
c = b; // 把b赋给c
b = null; // b变为默认值
}
// ...
}
3.1.2 rest参数 (ES6新标准)
function foo(a,b,...rest){
console.log('a='+a);
console.log('b='+b);
console.log(rest);
}
foo(1,2,3,4,5) //结果:a=1,b=2,Array[3,4,5]
//多余的参数将以数组形式交给变量rest,所以不再需要arguments我们就获取去了全部参数
3.1.3 ES6中解构赋值
var [x,y,z] = ['hello','java','es6'];
console.log('x = ' + x + ', y = ' + y + ', z = ' + z);
//输出x = hello, y = jave, z = es6
4.1 循环与判断
4.1.1 for循环
var att = ['xx',11,'ss','z'];
var i;
for(i=0;i<att.length;i++){
var aa = att[i];
console.log(aa);
} //遍历出 xx,11,ss,z
//breck表示退出循环
for(;;){ // 是个死循环
..
}
4.1.2: for..in循环可以把一个对象的所有属性依次循环出来
var o = {
name:'xx',
age:12,
city:'jiangxi'
};
var o2= [1,2,'xx'];
for(var key in o){
console.log(0key); // name,age,city 只是遍历属性,并不是遍历出值
console.log(02[i])
}xxxx
4.1.3 switch
switch(age){
case 18:console.log('xxx');
case 22: console.log('xxxxx');
break;
}
4.2.1 if判断
if (){ //默认使用 === 进行判断,即既判断类型,又判断值
}else if(){
}else{
}
4.3.1 Swith/Case
switch(age) {
case 18:
console.log("you should study")
case 22:
console.log("you should go to work")
break; //使用 break 跳出分支
case 60:
console.log("you should have a rest")
break;
default:
console.log("我没有什么好提醒你的")
} //使用 default 表示其他分支都不匹配的情况,可以省略
4.4.1 三目运算
- 简短,快捷
- 没有return,不能写复杂句式
boolend? 分支1:分支2
条件? 判断1:判断2
5.1 基于原型链的继承: proto
var na = {
play: function(){console.log('呐')}
}
var xiaoming = {
name:'小明',
age:18
}
xiaoming._proto_ = na;
//将xiaoming的爸爸指定为na,那么,xiaoming将可以用na的所有属性方法
//通过 __proto__ 去寻找其父
编程的潮流是简便、高效率,
为了让事情变得简化,我们可以写入函数中,使用函数消除冗余
var person = {
ear:function() { console.log('xx')}
}
function(name,age){
var a = {
name:name,
age:age
}
}
a._proto_=person; //指定父类为person,获取父类的属性.
return a ;
var xiaohong = createStudent('小红',18); ...
再如JS提供的一种内部语法
function person(){
this.ear = function() { console.log('xx')}
}
function ag(name,age){
this.name = name,
this.age = age
}
ag.prototype = new Person();
var xiaohong = new ag('小红',18);
6.1 JavaScript核心内置对象
String -字符串
Math -处理数学运算
Date -提供操作日期和时间的方法
Array - 数组模型,储存数据
Function - 提供构造新函数的模板
Object - 包含js对象所共享的基本功能
RegExp - 表述了一个正则表达式对象
6.1.1Math :主要作用在Number, 进行数学运算
Math.randon();//求随机数
Math.pow(4,2) //4的二次方
Math.sprt(4) //开根号2
Math.exp(2); //自然指数
Math.randon().toFixed(2);//取前两位数.
6.2.1Date:时间
let d = new Date();
let d = new Date('2010-08-04');
let d = new Date('1995-12-17T03:24:00');
let d = new Date("October 13, 1975 11:13:00");
let d = new Date(79, 5, 24); // 年月日
let d = new Date(79, 5, 24, 11, 33, 0); // 年月日时分秒(创建指定日期时间)
d.setFullYear(2010,0,14); // 2010.1.14
6.3.1 RegExp :正则匹配
var re2 = new RegExp('ABC\\-001');
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
6.4.1 数组的建立
var arr = [1, 2, "hello", true];
arr.length // 4 从0开始
arr.concat([33, 44]) // [1, 2, "hello", true, 33, 44]
arr.flat(); // 将其压平
arr.includes(); // 判定是否存在某个元素
arr.indexOf/lastIndexOf(1); // 判定某个元素的序号
arr.slice(); // 复制
arr.splice(3); // 删除、添加,默认行为是删除从 3 到最后一位的元素,返回被删除的元素组成的数组
arr.splice(3, 1); // 删除多少个元素
arr.splice(2, 0, 11111); // 添加
arr.reverse(); // 将数组内元素反向排序,注意,它是一个破坏性的函数
arr.sort(); // 排序,破坏性的函数
arr.sort(function (a, b) { if (a > b) return -1; else return 1 });
6.4.2 数组的基本语法
var arr = [1, 2, "hello", true];
arr.length // 4
arr.concat([33, 44]) // [1, 2, "hello", true, 33, 44]
arr.flat(); // 将其压平
arr.includes(); // 判定是否存在某个元素
arr.indexOf/lastIndexOf(1); // 判定某个元素的序号
arr.slice(); // 复制
arr.splice(3); // 删除、添加,默认行为是删除从 3 到最后一位的元素,返回被删除的元素组成的数组
arr.splice(3, 1); // 删除多少个元素
arr.splice(2, 0, 11111); // 添加
arr.reverse(); // 将数组内元素反向排序,注意,它是一个破坏性的函数
arr.sort(); // 排序,破坏性的函数
arr.sort(function (a, b) { if (a > b) return -1; else return 1 });
var xx = [1,3,2,'hello'];
xxs.indexof(1); //元素1的索引为2
var a = [1,2,3,4,5,6,7,'ss'];
a.slice(2,4); //从索引2开始到4之内的所有值,不包括4 为3,4
push()向Array的末尾添加若干元素
var arr = [1,2];
arr.push('a','c');
arr; //[1,2,'a','c']
unshift()向Array的前面添加若干元素
arr.unshift('x'); // ['x',1,2]
pop()则把Array的最后一个元素删除掉
arr.pop(); //将'c'删除 ,重复多次,将多次删除
shift()则把Array的第一个元素删除
arr.shift(); // 将1删除,重复多次,多次删除
sort()对Array进行排序,会直接修改当前Array的元素位置
arr.sort();
reverse()把整个Array的元素反转排序
arr.reverse();
splice()是修改Array的万能方法,可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
例:var arr = [1,2,'xxx'];
arr.splice(1,2,'xxx') 从1开始往后删除两个,包括1本身开始
concat()将Array和另一个Array连接起来,返回一个新的Array
var a = [1,2,3,4];
var b = a.concat([22,22,33]); //返回[1,2,3,4,22,22,33]
join()将Array的元素连接起来,返回连接的字符串
var a = ['a','x','s'];
a.join('-'); // a-x-s 如果不是字符串,将自动转换成字符串后再连接
6.5.1 typeof :获取对象的类型
typeof 123;//number
typeof 'str';//string
typeof null;//object
6.6.1包装对象
var n = new Number(123); //生成新的包装类型
//虽然看起来一样,但类型已经变成object,当原始和包装后的对象用=== 比较,会返回false
//所以少用包装对象
//用parseInt()或parseFloat()来转换任意类型到number;
6.7.1 window对象:充当全局作用域,而且表示浏览器窗口
window.innerWidth //页面长度
window.innerHeight //页面高度
6.8.1 JSON语法
在JSON出现之前,大家一直用XML来传递数据
//JSON语法是JAVAScript对象表示语法的子集
//格式为:
JSOn名称:值 如:"key":"value"
//key[0].value 可访问 ,JSON与XML都用于接收web服务端的数据
--JSON实例:
{
"sites": [
{ "name":"菜鸟教程" , "url":"www.runoob.com" },
{ "name":"google" , "url":"www.google.com" },
{ "name":"微博" , "url":"www.weibo.com" }
]
} //JSOn更简短,不需要结束标签,可以使用数组
//XML需要XML解析器来解析,JSON直接用JavaScript函数来解析
//通过JSON.parse(); 将JSON字符串转换成JS对象
//JSON.stringify(); 将JS值转换为JSON字符串
--XML实例:
<sites>
<site>
<name>菜鸟教程</name> <url>www.runoob.com</url>
</site>
<site>
<name>google</name> <url>www.google.com</url>
</site>
<site>
<name>微博</name> <url>www.weibo.com</url>
</site>
</sites>
7.1 DOM节点:文档对象类型
第一种:
//在操作一个DOM节点前,我们需要通过各种方式先拿到这个DOM节点。最常用的方法是:
document.getElementById('xx') //id
document.getElementsByTagName('xx') //元素标签
document.getElementsByClassName('div') //CSS选择器
document.write(x.getAtteribute("属性名"))//返回目标对象指定属性的属性值
x.setAttribute("title","图书列表"); // 修改元素节点的属性值
x.removeAttribute() //删除指定元素的属性
//小知识:因为这些方法繁琐,不够简便灵活,所以出现了第三方的框架,如jQuery.简化了dom操作,$();
查找节点的另一种:Element节点
//querySelector 只返回一个
//querySelectorAll 返回一个NodeList 类似Array的对象
element.querySelector("div")/(".xxx")/("#xx")
/(div > span)/(div span)
element.querySelectorAll('img');
document.querySelector('#test-js');
7.1.1 定位节点
m.childNodes; // 显示所有的孩子节点
m.children; //显示孩子节点
m.childNodes[2] //使用数组,获取第2个孩子节点
m.parentNode; //引用当前节点的父节点
m.childNodes[3].prevSibling; // 上一个兄弟节点
m.childNodes[3].nextSibling; // 上下个兄弟节点
test.firstElementChild // 获取节点test下第一个子节点
test.lastElementChild; //获取最后一个子节点
// 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr');
7.1.2 修改
在选中了某个节点后,我们可以修改:
m.firstChild.nodeValue = 'xxx';
m.childNodes[1].innerText = 'xxxxxxx';
//关键词 : innerText ,nodeValue
innerHTMl :可以修改DOM节点的内容,还可以修改DOM节点的子树
7.1.3 新建,附加节点
//添加一个文本节点:appendChild
var t = document.createTextNode('世界和平');
m.appendChild(t);
//appendChild:把一个子节点添加到父节点的最后一个子节点
//insertBefore : 子节点插入指定位置
xx.insertBefore(子节点,xx) //将子节点插入xx节点的上面
list.appendChild(js); //父节点.appendChild(子节点);
//添加一个元素节点:insertBefore
m.insertBefore();
//添加一个注释节点:appendChild
m.appendChild();
//创建一个节点
var a = document.createElement('p');
a.id = 'aa'; //给节点添加id
a.innerText = 'xx';
7.1.4 替换,删除
//必须从父节点开始替换,删除
m.replaceChild(); //替换节点
m.removeChild(); //删除节点
7.2.1 API
attributes 获取节点上的所有属性
getAttribute/setAttribute 获取/设置属性
8.1 事件
8.1.1 event
event.x,event.y,获取鼠标的位置
8.2.1 浏览器事件
- window.onload — 浏览器载入文档事件
- window.onfocus — 浏览器获得焦点
- window.onblur — 浏览器失去焦点
- window.onscroll — 浏览器拖动滚动条
- window.onresize –改变窗口尺寸
8.3.1 HTML元素事件
用户与页面的交互发生在按钮,图片等系列HTML元素上的响应
例:
onclick -鼠标单击
ondbclick -鼠标双击
onmmouseout - 鼠标移出链接所在的位置
onmouseover - 鼠标经过链接所在的位置
onmouseup - 鼠标在链接的位置放开
onkeydown - 键被按下
onkeyup - 键被送开
onblur - 失去焦点
onfocus - 获得焦点
onchange - 文本内容改变
onkeypress - 按下并放开该键
当定义一个函数时,我们可以通过定时,来委托给浏览器调用
function xxx(){
console.log('时间延长');
}
//通过定时任务的方式,委托给浏览器调用:
setTimeout(xxx, 3000);
setInterval(xxx, 3000);
//通过事件的方式,委托给浏览器监听并触发调用:
document.querySelector('button').onclick = xxx;
9.1 异步请求:AJAX
AJAX=异步JavaScript和XML
是用于创建快速动态网页的技术
9.1.1 XMLHttpRequest对象
XMLHttpRequest用于在后台与服务器交换数据
//创建XMLHttpRequest对象
var iable = new XMLHttpRequest();
//在陈旧的IE5、IE6中,用ActiveXobject
var iable=new ActiveXObject("Microsoft.XMLHTTP");
//使用open()、send()方法将请求发送到服务器
open(method,url,async)
如:xmlhttp.open("GET","ajax_test.asp",true);
//method:请求的类型;GET 或 POST
//url:文件在服务器上的位置
//async:true(异步)或 false(同步)
send(string) //string:仅用于 POST 请求
10.1作用域及模块化
var:使用var定义的数据作用域,是函数级别的.
let/coust:块级作用域 优先使用级:const>let>var
在ES6中推出了标准的模块写法
- 模块文件中export
- 在使用的地方import
//模块的导出
var name = 'tom';
var hello = function(){alert('Hello,World')};
export {name,hello};
或:在声明时,一齐导出
export var aa = 'xx';
export default 'heelo world'; //默认导出,只可一个
//模块的引用
<script type="module">
import{name,heelo} from "js的路径";
import * as x from "路径"; //通过as 来进行赋值或者换命名
//尽量将模块分成多个js文件,每个js文件可成一个模块;
</script>