初学javascript一周总结

67 阅读11分钟

JavaScript:简称JS,是一个运行在客户端浏览器的【解释型】【弱类型】【面向对象】脚本语言

编译型:在运行程序之前,需要先检查语法是否正则,如果不正确,直接不允许运行,比如:Java/C++...

解释型:在运行程序之前,不需要先检查语法是否正则,直接执行,但是碰到错误就会停止后续代码 - 更加自由,比如:JavaScript...

弱类型:变量保存的数据是可以随意的,数据类型是由数据来决定的 - 更加的自由 1 - Number 数字 “1” - String 字符串

强类型:变量保存的数据,是由数据类型来决定的 - Java - 更加的严格 面向对象 以后可能会经常看到一种写法 对象名.属性名; 对象名.方法名();

特点: 1、可以使用一切编辑器工具编写js代码,编辑器并不代表你的实力 2、解释型 3、弱类型 4、面向对象编程方式 5、可以做一切css完成不了的效果(轮播/选项卡/购物车/验证/数据渲染...)

如何使用JS 1、使用方式:2种 1、直接在HTML页面上写一个script标签,里面就可以书写你的js代码 2、外部js,进行引入 1、创建一个xx.js的文件,里面书写js代码 2、在HTML页面引入

2、输出方式/打桩输出:帮助我们检查错误:3种 *1、在控制台输出日志:console.log(想要输出/查看的东西); - 会在F12的console显示日志 2、在页面上输出日志:document.wrtie(想要输出/查看的东西); - document当前文档 write写入:在页面上输出,而且支持识别标签 - 垃圾:如果绑定了点击事件后输出,会把页面上原来的HTML和CSS都全部替换掉 3、在警告弹出框输出日志:alert(想要输出/查看的东西); - 在一个浏览器自带的弹出框中输出日志,但是弹出框会卡住页面,用户只能看到一个白板 - 垃圾

*变量和常量: *变量:创建后,值可以再次修改 何时使用:以后反复使用到的数据,都要提前把他保存在一个变量中,以后使用变量名,相当于就是在使用变量的值 如何使用:var 变量名=值; 特殊: 1、变量名其实不是随意的 1、不能以关键字命名 2、不能以数字开头 3、建议下划线命名法 或 小驼峰命名法 name,age,gender,weight,height,hobby - 推荐

xingming,nianling,xingbie,tizhong,shengao,aihao - 不推荐 更不推荐:a,b,c,d,d1,d2,d3... - 此变量名无意义 2、如果你的变量名是name,不管你保存的数据是什么数据类型,都会悄悄的给你转变成一个字符串 3、多个变量创建可以简写: var 变量名1=值1,变量名2=值2,....;

常量:创建后,值不可以再次修改,只能设置一次值 生活中的常量: PI - 3.1415926.... 一个小时60分钟.... 一天24个小时 一年365/366天 语法:const 常量名=值; - 垃圾

*算术运算符:+ - * / % 1、%:读作取余,俗称模,两个数相除,不去商,而取除不尽的余数 固定套路: 1、*判断奇偶性:num%2,结果为0说明是偶数,结果为1说明奇数 - 以后可以用于判断 2、获取一个数字的倒数n位 1234%10 -> 4 1234%100 -> 34 1234%1000 -> 234

*****特殊:其实算数运算符具有隐式类型转换,默认转为数字在运算 +运算:如果左右两边但凡出现了一个字符串,那么悄悄的都转为字符串,+运算不再是+运算,而是字符串的拼接

-*/%:字符串也可以变为数字,但是前提:必须是纯数字组成的字符串才可以 如果字符串包含了非数字字符,直接转为NaN

NaN:Not A Number - 不是一个数字,但是确实是数字类型,全是缺点: 1、参与任何算术运算,结果仍为NaN 2、参与任何比较运算,结果都是false

*数据类型:分两大类 1、原始/基本/值类型:5个 1、Number - 数字,取值:无数个 2、String - 字符串,取值:无数个,必须写上'' 或 "" 3、Boolean - 布尔,取值:两个:true/false - 往往用于判断比较的条件处使用 4、Undefined - 取值:1个:undefined,创建了一个变量,但是没有赋值,默认值为undefined,祖师爷犯的错,用来做大部分操作都会报错! 5、Null - 空,取值:1个:null,释放变量/内存,节约内存空间

引用/对象类型:11个引用类型的对象(很多很多的属性和方法)

扩展: 分支结构:判断条件的不同选择对应的代码去执行,执行了一条路就不会再走别的路 如何使用: 一个条件,一件事,满足就做,不满足就不做 if(判断条件){ 操作; }

一个条件,两件事,满足就做第一件,不满足就做第二件 if(判断条件){ 操作; }else{ 默认操作; }

多个条件,多件事,满足谁就做谁 if(条件1){ 操作1; }else if(条件2){ 操作2; }else if(条件3){ 操作3; }else{ 默认操作; }

特殊: 1、else if...你想写多少个随便,根据你的需求自己判断 2、最后else可以省略不写,如果条件都不满足,那么什么事都不会执行,你的分支就白写了 3、书写判断顺序,需要根据你的需求来写,不能乱写顺序

用户输入弹出框: var user=prompt("提示文字","默认值") ***数据类型转化:不同的数据类型做操作可能出来的结果是不一样的 Number + Number = Number Number + String = String

JS获取页面上的一切东西,数据类型默认都是一个字符串

如果你想要查看数据类型:typeof(想要查看的东西);

*****算术运算符的隐式转换:目的:就算不用输出看,我心里也知道最后的结果是什么 默认:悄悄的将左右两边的东西,转为一个数字,在运算

特殊:1、+运算,碰上一个字符串,左右两边都会悄悄的转为字符串,+运算不再是+运算,而是字符串拼接操作

2、原来别的数据类型其实也可以转为数字 true->1 false->0 undefined->NaN null->0

3、其实-*/%,字符串也可以转为一个数字,前提要是一个纯数字组成的字符串才行,但凡包含一个非数字字符就转为NaN "1000"->1000 "1000px"->NaN

4、NaN:Not A Number:不是一个数字,但是确实是数字类型,不在三界之中,不是一个有效数字 2个缺点: 1、NaN参与任何算术运算结果都是NaN 2、NaN参与任何比较运算结果都是false,甚至不认识自己 问题:我们没有变法使用普通的比较运算来判断x是不是NaN 解决:个人更爱反用:!isNaN(x) true->是一个有效数字 false->是一个NaN

学完了算术运算的隐式转换,但我们依然没有解决一个事 "100px"+100 -> "100px100" "100px"-*/%100 -> NaN

显示/强制转换:隐式转换出来的结果不是我们想要的,我们程序员就要手动调用一些方法,强制转为我们需要的类型,再做操作 1、转字符串:var str=x.toString();//x不能是undefined或null,因为undefined和null不能使用任何的.操作 页面上的一切东西,数据类型默认都是一个字符串

***转数字: 1、*parseInt(str/num); parse->解析 Int->整型 执行原理:专门为字符串和小数转为整数数字准备的,从左向右依次读取每个字符,碰到非数字字符,就停止转换, 如果一来就碰到了不认识的,则为NaN console.log(parseInt(100.5));//100 console.log(parseInt("100.5"));//100 console.log(parseInt("100px"));//100 console.log(parseInt("1px00"));//1 console.log(parseInt("px100"));//NaN console.log(parseInt(true));//NaN console.log(parseInt(false));//NaN console.log(parseInt(undefined));//NaN console.log(parseInt(null));//NaN

*parseFloat(str); parse->解析 Float->浮点型 执行原理:几乎和parseInt一致,认识第一个小数点

、Number(x);//此方法是万能的,任何人都可以转为数字 //垃圾:完全等效于隐式转换,我们还得多记忆一个方法,没必要,还不如 x -0 *1 /1 %1

*****Function的基础: 1、Function:函数,称之为方法:需要提前【预定义好】的,以后就可以【反复使用】的【代码段】 现实生活中:所有的方法都是需要提前学习的,是不会忘记的所以可以反复使用 其实一阶段你就见过很多函数了,比如: rotate(360deg) - 完成了一个根据角度值顺时针旋转360度的功能 url(图片路径) - 完成了一个根据图片路径显示图片的功能

js中要学习自定义函数:完成了一个。。。。。。。的功能

2、如何使用:2步 1、定义/声明/创建函数: function 函数名(){ 若干的代码 }

2、调用/使用函数: 1、要么在js中程序员直接写死,要执行几次:函数名(); 2、交给用户绑定在某个元素上,写上点击事件,让用户来触发: 内容

3、何时使用: 1、*不希望打开页面立刻执行,而需要时再使用 或 由用户来触发 2、*希望能够反复执行,不用刷新页面 3、以后任何一个独立的功能体,都要单独封装为一个函数(你的每一个作业) 4、函数的地位非常高,函数是第一等公民地位,随时随地考虑能不能封装为一个函数,尤其是重复的代码 5、函数内的一切内存,函数调用完毕后都会自动释放

4、带参数的函数: 榨汁机 -> 函数:榨汁 原材料 -> 参数 创建:形参:形式参数,其实就是一个变量,但是不需要写var,而且默认也没有保存任何值,默认值为undefined function 函数名(形参,形参,...){ 函数体; }

使用:实参:实际参数,真正的值,需要再你调用时再传入 函数名(实参,实参,...)

特殊:1、传实参的顺序一定要和形参的顺序一一对应,并且数量也要对应 2、不是一定要带参数的函数才是好函数,具体情况,需要具体分析: 如果你的函数体就是固定的 - 则普通函数 如果你的函数体希望根据传入的实参不同,做的略微不同 - 则带有参数的函数

***分支结构: 1、程序的流程控制语句:3种 1、顺序执行 - 默认,从上向下的依次执行 2、分支结构 - 通过条件的判断,选择部分代码执行 3、循环结构 - 通过条件的判断,选择要不要重复执行某些代码

2、比较运算符:> < >= <= == != 用于做判断/比较的 结果:一定是一个布尔值 强调:如果你想要判断多个条件,绝对不能像小时候数学的写法:18<=age<=65,错误的! 解决:逻辑运算符

3、逻辑运算符: &&:与,并且:要求全部条件都要满足,最后的结果才为true 只要有一个条件不满足,结果则为false

||:或:要求全部条件都要不满足,最后的结果才为false 只要有一个条件满足,结果则为true

!:颠倒布尔值!isNaN(x)

***循环结构: 问题:在控制台打印输出1000句hello world console.log("1hello world"); ... console.log("1000hello world");

循环结构:反复执行 【相同 或 相似】的操作 循环三要素: 1、循环条件:开始 - 结束,循环的次数 2、循环体:做的操作是什么 3、循环变量:记录着我们当前在哪一次,而且他会不断的变化,往往都会向着不满足循环条件进行

1、while循环: 语法: var 循环变量=几; while(循环条件){ 循环体; 循环变量变化; } 执行原理:首先创建了循环变量,然后判断条件,如果条件满足,则做【一次】循环体操作,并不会退出循环,回过头继续判断条件满足吗,如果满足,则再做【一次】循环体操作....... 直到循环条件不满足,才会退出循环 宏观上感受循环一瞬间就结束了,但是微观上来说其实是【一次一次】执行的

特殊: 1、有的时候真可能不知道从何开始,到何处结束,死循环:永远不会停下来的循环 何时使用:不确定循环次数的时候 while(true){ 循环体; } 退出循环语句:break - 只能在循环中使用,多半都是搭配死循环使用的

2、*for循环 语法:for(var 循环变量=几;循环条件;变量的变化){ 循环体; }

死循环: for(;;){ 循环体; }

面试题:while 和 for 的区别? 语法上有区别,但两者都能做到相同的操作 一般来说我们不确定循环次数的时候,会使用while循环 - 死循环 一般来说我们确定循环次数的时候,就用for循环 - 更漂亮更简洁,大部分情况都会使用它

*****数组的基础 问题:保存1000个同学的名字? var name1="张三丰1"; ... var name1000="张三丰1000";

不推荐,变量其实就是我们所谓的内存,变量创建的越多,那么我们内存空间消耗就越大,那么网站的性能就会越差

解决:数组:创建一个变量可以保存【多个数据】的集合 数组都是线性排列,除了第一个元素,每个元素都有唯一的前驱元素 除了最后一个元素,每个元素都有唯一的后继元素 ***每个元素都有一个自己的位置,称之为叫做下标,下标是从0开始的,到最大长度-1

创建数组:2种 1、*直接量方式: var arr=[];//空数组 var arr=[数据1,....];

构造函数方式: var arr=new Array();//空数组 var arr=new Array(数据1,....);//而且这个方法还有一个坑

获取数组中的数据 数组名[下标];

添加/替换 数组名[下标]=新值; 下标处有没有元素,如果没有则为添加,如果有了就为替换

数组具有三大不限制 1、不限制元素的个数 2、不限制元素的类型 3、不限制元素的下标越界 - 不是一个好东西了 如果获取元素,下标越界,返回的一个undefined 如果添加元素,下标越界,会得到一个稀疏数组,导致下标不再连续,如果搭配上循环去遍历每一个元素的话,我们会得到很多很多的undefined 问题:自己数下标,是不科学的,很有可能就会数错

解决:数组中唯一的属性:长度:数组名.length - 获取当前数组的长度:最大下标+1 三个固定套路: 1、获取倒数第n个元素:arr[arr.length-n] 2、始终向末尾添加元素:arr[arr.length]=新值; 3、缩容:删除倒数n个元素:arr.length-=n

前面的下标好数,后面的下标也好数,但是中间的下标还是不好数

***往往很多情况,我们不会拿出某个元素来使用,而是拿出所有的每个元素来进行 相同 或 相似的操作 遍历数组:把数组中的每个元素拿出来执行相同相似的操作 公式: for(var i=0;i<数组名.length;i++){ console.log(数组名[i]);//当前次元素 }

DOM:Document Object Model:文档对象模型:专门用于操作HTML文档的,提供了一些属性和方法等待我们学习

DOM树概念:DOM将我们的HTML看做了是一个倒挂的树状结构,但是树根不是html标签,而是document对象 document对象:不需要我程序员创建的,由浏览器的js解释器自动创建,一个页面只有一个document 作用:可以通过树根找到我们想要的任何一个DOM元素/节点/对象(属性和方法) DOM会将页面上每个元素、属性、文本、注释都会当作一个DOM元素/节点/对象

查找元素:

通过ID查找元素 语法:var elem=document.getElementById("id值"); 特殊: 1、返回值,找到了返回的是一个当前找到的DOM元素,没找到,返回一个null,做了别的操作可能就会报错了 2、找到了多个相同的id,那么只会返回第一个 3、*垃圾方法, 一次只能获取一个元素,也只能操作一个元素,麻烦 4、其实根本不需要使用此方法,直接写ID也可以找到元素

通过标签名查找元素 语法:var elems=document/已经找到了的父元素.getElementsByTagName("标签名"); 特殊: 1、返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合 2、*JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素 3、不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了

通过class名查找元素 语法:var elems=document/已经找到了的父元素.getElementsByClassName("标签名"); 特殊: 1、返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合 2、*JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素 3、不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了

通过关系查找元素:前提条件:必须先找到一个元素才可以调用关系网 父元素:elem.parentNode; 子元素:elem.children; - 集合 第一个儿子:elem.firstElementChild; 最后一个儿子:elem.lastElementChild; 前一个兄弟:elem.previousElementSibling; 后一个兄弟:elem.nextElementSibling;

强调:DOM集合不能直接做操作!

操作元素:前提:找到元素才能操作元素:<标签 属性名="属性值" style="样式">内容</标签>

1、*内容: 1、*innerHTML:获取 和 设置 开始标签到结束标签之间的内容 - 支持识别标签 获取:elem.innerHTML; 设置:elem.innerHTML="新内容";

2、innerText:获取 和 设置 开始标签到结束标签之间的文本 - 不支持识别标签 获取:elem.innerText; 设置:elem.innerText="新文本";

以上两个属性都是为双标签准备的,但是操作不了单标签input的内容

3、*value:专门为input的value值准备的 获取:input.value; 设置:input.value="新值";

*属性: 获取属性值:elem.getAttribute("属性名"); 设置属性值:elem.setAttribute("属性名","属性值");

简化版: 获取属性值:elem.属性名; 设置属性值:elem.属性名="新属性值"; 缺陷: 1、class必须写为className - 2015年过后,ES6诞生过后,class变成了一个关键字 2、不能操作自定义属性,只能操作标准属性

*样式 使用样式的方式: 1、*内联/行内样式 2、内部样式表 3、外部样式表

二阶段我们就是要用js来操作【内联样式】 1、不会牵一发动全身 2、优先级最高

获取:elem.style.css属性名; 设置:elem.style.css属性名="css属性值"; 特殊: 1、css属性名,有横线的地方,去掉横线,变为小驼峰命名法 border-radius -> borderRadius 2、目前学习的,获取时,只能获取内联样式 - 小缺点,我们可以忽略掉,就算以后我交了你操作样式表,你也不会去使用

绑定事件: elem.on事件名=function(){ 操作; *****this关键字:目前只能用于事件内: 如果单个元素绑定事件:this->这个元素 如果多个元素绑定事件:this->当前触发事件的元素 }

总结: 获取 - 往往都是用与判断比较 设置 - 就是添加/修改