什么是JS
js是JavaScript的缩写,是一种编程语言,也是我们做前端的核心技术。它与html,css的相同之处在于,都可以放在浏览器中运行,不同之处是html,css不叫编程语言,且js的运行可以不在浏览器中。
js的基本语法
- js区分大小写
- 忽略空白符
- 语句分号可以加也可以不加(不过最好保持一致)
- 注释 单行注释“//” 多行注释“/* */”
- 标识符和关键字
eg:var a=100;
var就是关键字;a是标识符
在js中,什么是变量
- 变量:变量就是内存中的一个地址
- 变量名:内存空间的别名
- 内存空间地址:就是一块内存空间的地址,可以通过地址操作它所对应空间的数据
- 变量值:内存空间中的数据
- 数据:打开一个软件页面上有很多数据,也叫状态,可存在内存,也可以放在硬盘上(放在内存里如果断电,内容就会消失,存在硬盘上就不会,相当于ctrl+s)
变量的分类
- 全局变量:函数外面的量,全局变量在函数内外都能访问。
- 局部变量:函数内部定义的量,只能在函数内被调用。
(没有加var的量都是全局变量,无论是在函数内定义还是函数外定义;对于在var的量,如果是在函数外定义,则是全局变量,否则就是局部变量)
数据类型
- 基本数据类型
number:数字,不分整数还是小数
string:字符串,不分字符还是字符串,需要注意的是,在定义字符串的时候需要加‘’或者“”,否则计算机会把它当成变量,而且不能单引号套单引号或者双引号套双引号,必须交叉使用
boolen:只有两个值,true false
undefined、null:都表示没有值
nan:not a numbel - 引用数据类型
object:对象
array:数组
function:函数
如果想要查看一个数据是什么类型,可以通过typeof这个运算符:
console.log(typeof.a)就可以得到a是什么数据类型
js数据类型转换
- 隐式转换:计算机不知不觉的悄悄转换
- 强制转换:写代码转
console.log(**parseInt**(3.14)),小数转整数
console.log(**pareseInt**("2.14abc"))
console.log(**Number**("2.14"))
console.log(**string**(2.14))
等等
需要注意的是,if后面的()要么放false要么放true,如果放了一个非Boolean类型的数据也会悄悄转换为Boolean类型。一半转为false的有:0 -0 “ ” undefined null
js代码在执行时分两个阶段
- 预编译:提升(提升的对象是加var的声明,和function声明的函数)
eg:var a=100;var a 就是声明,也就是说var a会被提升,由于其对应的值不会被提升,使用在预编译时a对应的时undefined。
eg:function f(){console.log(“hhhh”)};此声明是函数名加函数体,也就是说整体会被提升
在js中只要提升了一次,就不会提升第二次
eg:var a=100;
function a(){
console.log("....")
}
在预编译时,var a提升,a对应的是undefined,由于a提升过一次,所以function a()不会被提升,仅仅提升其函数体,将函数体赋值给了a,也就是说此时a对应的是一个函数
2. 代码执行
加var和不加var的区别
- 加var的会在预编译时被提升,不加var的不会
- 不加var的都是全局变量,只要是全局的都会在GO里面存一份
执行上下文(EC)
- 全局执行上下文:全局代码在执行时会产生全局的EC,即EC(G)
全局代码参数的全局参数或者全局函数,会被存放在VO里,通常情况下也会在GO里面放一份,不过Go里面比VO多放了不加var定义的变量,且Go里面本身就有很多的内容 - 局部执行上下文:函数代码在执行时会产生局部的EC,且每调用一次函数,就会产生一个EC,产生的EC会被放入EC栈里面,一般调用完之后再出栈释放
在局部EC里面,需要这样考虑问题,第一步:看看有没有形参赋值;第二步:看看有没有提升;第三步:执行代码
在js中,基本数据类型被存放在栈中,引用数据类型被存放在堆中
初始函数
function f(a,b){
console.log("hhhh")
}
f(1,2)
其中,1,2表示实参,a,b表示形参。函数调用就是实参给形参赋值的过程。
函数属于调用数据类型,其函数名会被存放在栈中,其函数体会被存放在堆中,栈中函数名对应的是函数体在堆中的地址。
let
- let声明的变量没有提升
- let配合{}使用也可以形成块级作用域
eg:if(true){
var a=100;//全局变量
let b=888;//b只能在if里面被访问
}
- 使用let声明的变量不会挂载到Go上
- 使用let不能重复声明
eg:let a=8;let a=100;是错误的
const
const声明的是常量,即不会变化的量,其基本语法和声明说的let一样,不过const在声明常量时必须要赋值
闭包
在调用完一个函数后,函数本该被释放,但是函数内的某些变量在别处被使用,使得函数不能释放,就形成了所谓的闭包。一部分人是这么认为:在一个函数内部嵌套了一个函数,并且里面的函数引用外面的函数的变量里面的函数就可以叫闭包。
**闭包的好处:**可延长一个局部变量的生命周期
**闭包的坏处:**会成为常驻空间,造成内存泄漏
eg:var i=0;
function a(){
var i=10;
function x(){console.log(i)}
return x;
}
var y=a();
此时就形成了一个闭包,因为i被调用,得不到释放
内存泄漏
什么是内存泄漏?
一些小语法
- var a=b=2;表示的是var a=2;b=2。
- var a=2,b=2;表示的是var a=2;var b=2。
- 函数没有返回值的话,默认返回underfine。
- 作用域链:描述找数据的链。
- b.m=b={n:666};表示{n:666}的堆地址同时赋给了b和b.m。
- undefine对应的值还是undefine。
js字符串换行
效果:
代码:
let huanhang='name:'+'yangshuo'+'\n'+'age:'+'20'
console.log(huanhang)
js模板字符串使用
例子:
this.monthImg1 = `static/images/haibao1111/haibao-images${index.month}.png`
给变量用${}包住,整个字符串用``包住。
js数组添加动态对象,对象键名不固定
this.answerArr.push({[`info${this.currentIndex+1}`]:this.qustionArrNow[this.currentIndex].answer[this.currentAnswer].title})
js对象添加动态属性,属性不固定
this.answerArr[`info${this.currentIndex+1}`]=this.qustionArrNow[this.currentIndex].answer[this.currentAnswer].title
vue获取数据
eg:
获取:
this[`checkAllGroup${index+1}`]
js动态调用函数
function meb_sur1(obj){
console.log("1111111")
}
function meb_sur2(obj){
console.log("2222")
}
function meb_sur3(obj){
console.log("33333")
}
function meb_sur4(obj){
console.log("44444")
}
function meb_sur0(obj){
console.log("000000")
}
for(let i=0;i<5;i++){
let e=eval(`meb_sur${i}`);
e()
}
jquery点击动态添加类名
效果:
html:
<div class="zx-page">
<div class="zx-page-one zx-page-active">1</div>
<div class="zx-page-one">2</div>
<div class="zx-page-one">3</div>
<div class="zx-page-one">4</div>
<div class="zx-page-one">5</div>
<div class="zx-page-one">6</div>
<div class="zx-page-one">7</div>
<div class="zx-page-one">...</div>
<div class="zx-page-one">12</div>
<div class="zx-page-one">13</div>
<div class="zx-page-p">跳转到</div>
<div class="zx-page-one"><input type="text"></div>
<div class="zx-page-p2">页</div>
<div class="zx-page-btn">跳转</div>
</div>
js:
$(".zx-page").children().click(function(){
let index=$(this).index()
$('.zx-page .zx-page-one').removeClass('zx-page-active')
$('.zx-page .zx-page-one').eq(index).addClass('zx-page-active')
});
js实现按钮倒计时一分钟不能再点
效果:
html:
<div class="sure-button">确定</div>
js:
function countDownFun(){
if(!Number(localStorage.getItem("isEnding"))){
return;
}
localStorage.setItem("isEnding",0)
let lastTime=60
$(".sure-button").css("background-color","#666")
$(".sure-button").html("确定"+"<span class='number'>"+lastTime+"</span>"+"s");
let _setInterval = setInterval(() => {
if (lastTime <= 1) {
$(".sure-button").text("确定");
$(".sure-button").css("background-color","green")
localStorage.setItem("isEnding",1)
clearInterval(_setInterval);
return;
}
lastTime--
$(".sure-button").css("background-color","#666")
$(".sure-button").html("确定"+"<span class='number'>"+lastTime+"</span>"+"s");
}, 1000);
}
$(".sure-button").click(function(){
countDownFun()
})
js监听页面是第一次进入还是刷新
if(window.name == ""){
//第一次进入
window.name = "isReload";
}else if(window.name == "isReload"){
//页面刷新
}