var a = 111; console.log(a.toString()); // xx.toString() 转字符串,undefined和null不能使用,因为他们两个不能用.方法 console.log(String(a)); // Strung()转为字符串,万能,但是不用,完全等效于隐式转换 // 转字符串不常用,应为从页面上获取的都为字符串格式
var b = '2px';
console.log(parseInt(b));
// parseInt--转数字(转为整数,不可识别小数点,可识别单位,当遇到不是数字的就停止转换,如果一开始就不是数字就转为NaN)
var c ='2.2px';
console.log(parseFloat);
// parseFloat - 转数字,可以识别第一个小数点,可识别单位,当遇到不是数字的就停止转换,如果一开始就不是数字就转为NaN
var d = '4';
console.log(Number(d));
// Number()-转数字,不用,完全等于隐式转换
// Boolean(xx):转布尔(不用),只有6种情况下为false:0 null undefined NaN '' false,其余均为true
// 比较运算符:> < >= <= == != === !== 返回的结果为boolean类型
// 特殊:1.两个字符串比较,pk每个字符的unicode号 0-9< A-Z < a-z <汉字
// 建议记忆:汉字第一个字:一:4e00(ascii码:19968)
// 最后一个字:龥:9fa5(ascii码:40869)
// 2. NaN参与比较均为false,解决:!isNaN(xx),如果为数字返回true,不是数字返回false
// 3. undefined == null 要比较两者需要用到===(不仅数值相等,数据类型也要相等)
// 3、*逻辑运算符:
// &&:全部条件都为true,结果才为true
// 只要有一个为false,结果就为false
// ||:全部条件都为false,结果才为false
// 只要有一个为true,结果就为true
// !:颠倒bool值
// 特殊:***短路逻辑:只要前一个条件已经可以得出最终结论,则后续条件不会再执行
// &&:如果前一个条件满足,则后一个操作才执行,如果前一个条件不满足,则后一个操作不执行
// 实现了一个【简单】的分支:目的:简化if(){},操作只能【用一句话】
// 语法:条件&&(操作);
// 举例:if(total>=500){total*=0.8}
// total>=500&&(total*=0.8)
// ||:两个值中二选一 - 老IE(6/7/8)兼容
// 现在不用特别管住,看代老师玩玩就行
var sum = 20;
sum>=100&&(sum*=0.8);
// 短路逻辑,第一个条件满足时再执行第二个条件
console.log(sum);
// 三目运算 - 简化if...else if...else if...else
// 如何使用:
// 1、条件?操作1:默认操作;
// 2、条件1?操作1:条件2?操作2:条件3?操作3:默认操作;
// 特殊:
// 1、只能完成【简单】的分支 - 操作只能有一句话,其实以后很多分支里面可能真的就只有一句话
// 2、默认操作不能省略 - 会报错
自定义函数:方法,一段提前被定义好的,可以反复使用的代码段
1、如何使用:2步 1、*创建/定义/声明函数&返回结果:2种 1、*声明方式:用function关键字进行声明 - 并不是人人都有声明方式,只有个别人才有,而且声明方式一定是最简单的 只有3个人具有声明方式:变量、常量、函数,其余人最简单的方式也是直接量 function 函数名(形参,...){ 函数体 return 返回值; }
2、直接量方式:
var 函数名=function(形参,...){
函数体
return 返回值;
}
函数名其实也是一个变量名
2、调用函数&接住结果
var result=函数名(实参,...);
解释:return:本意退出函数,但是如果后面跟着一个数据,则可以将数据返回到全局作用域中,但是仅负责返回,不负责保存,所以我们需要自己创建一个变量接住函数调用的结果
return只能写一次,而且最好写在函数体的后面
何时使用:并不是任何时候都需要加return:
1、全局想要使用局部的
2、调用完函数还希望拿到函数的结果在后续还要做操作时
3、如果没有return,其实也有默认返回值undefined
2、***作用域:2个 1、全局作用域:全局变量 和 全局函数,在任何位置都可以访问/使用
2、函数/局部作用域:局部变量 和 局部函数,只能在当前【函数调用时内部可用】
有了作用域才有变量的使用规则:
优先使用自己的,自己没有找全局,全局都没有报错
***强烈建议:千万不要对未声明的变量直接赋值,导致全局污染
所有的变量在使用之前都一定要先var,不能对着没有var变量直接赋值
***哪些属于局部变量:2部分
1、直接在函数作用域中创建的变量
2、形参
问题:全局无法使用局部的?不符合现实生活
解决:看上面 - 创建函数部分
3、***声明提前 在程序执行之前 悄悄将var声明的变量和function【声明】的函数 集中提前到当前作用域的顶部 但是赋值留在原地 变量比函数更轻
我们程序员是看不见的,但是会悄悄执行的
注意:只会在鄙视题遇到:自己写代码开发时绝对不会遇到
1、你写代码的时候尽量要先创建后使用
2、你写代码的时候尽量不要出现重复的名字
鄙视:如果你看到先试用后创建,多半都是考你声明提前
4、***按值传递:两个变量之间进行赋值 1、如果传递的是原始类型的值:两个变量之间赋值,做操作,互不影响的 - 其实是复制了一个副本给对方
2、如果传递的是引用类型的对象:Array、Function
两个变量之间赋值,做操作,是会相互影响的 - 因为两个用的是同一个地址值
函数之所以能有5颗星:考点太多太多?
1、创建函数的方式 - 3种?
2、作用域带来了什么?变量的使用规则
3、声明提前
4、按值传递
5、重载 - 今天不学
6、闭包 - 今天不学
2、预定义的全局函数:前辈们(实现浏览器的程序员们)提前定义好,我们可以直接在任何位置使用的函数: 1、编码和解码: 问题1:url网址中不允许出现多字节字符,如果出现会导致乱码(没人看得懂) utf-8编码格式下,一个汉字占3字节 解决:前端工程师需要将用户输入的网址中的中文编码为单字节字符,后端工程师接住前端传来的东西解码为原文 编码:var code=encodeURIComponent("str"); 解码:var 原文=decodeURIComponent(code);
以前有用,现在没用:随着浏览器的不断升级,浏览器现在自带此功能
拿来玩玩一个低级的悄悄话
2、isFinite(num):判断num是不是在有效范围之内
三种情况会为false:分母为0,NaN,Infinity
3、重要的:parseInt/Float()、eval()、isNaN()
3、***分支结构:根据条件的不同,执行不同的操作 if...else结构 switch...case结构
语法:
switch(变量/表达式){
case 值1:
操作1;
break;
case 值2:
操作2;
break;
default:
默认操作;
}
注意:
1、默认只要满足一条路,会把后面所有的操作全都做完,解决:break:一般放在操作的后面,但是:1、最后default不需要加break, 2、如果连续的多个操作是一样的效果,也可以省略中间部分
2、不带有隐式转换
3、default可以省略不写
if vs switch:
switch:优点:效率相对较高,因为不需要做任何范围判断
缺点:不能实现范围判断,必须要知道用户有可能输入的结果是什么才能使用
if :优点:实现范围判断
缺点:效率相对较低
个人建议:js优化,尽量的将if 优化为:三目、短路、switch
循环结构:反复执行 相同 或 相似的操作 1、while循环: 语法:var 循环变量=几; while(循环条件){ 循环体; 变量变化; }
2、do...while循环: 语法:var 循环变量=几; do{ 循环体; 变量变化; }while(循环条件)
面试题:while 和 do...while的区别?
只看第一次,如果第一次大家都满足条件,两者没有区别,无非do...while更麻烦
如果第一次大家都不满足条件,while一次都不会执行,而do...while至少会执行一次
3、***for循环: for(var 循环变量=几;循环条件;变量变化){ 循环体; }
其实我们的循环目前为止就算学完了,但是后面我们还会看到一些for in循环、for of循环、forEach循环 - 这些都算不上循环,因为不能自己设置从何开始到哪里结束,更算是专门用于遍历数组的操作
4、循环终止语句: *break - 退出整个循环 continue - 退出本次循环
2、*****数组的基础:一个变量可以保存多个数据 1、创建:2种 1、直接量:var arr=[值1,....]; 2、构造函数:var arr=new Array(值1,....);//缺陷:面试中:new Array(3);设置一个长度为3的空数组
2、访问:
获取:arr[i]; - 特殊:下标越界:得到undefined
添加/替换:arr[i]=新值; - 特殊:下标越界:得到稀疏数组
3、*3大不限制:
不限制长度、类型、下标越界(不是好东西)
4、length的三个固定套路:
获取倒数第n个元素:arr[arr.length-n];
向末尾添加元素:arr[arr.length]=新值
缩容:arr.length-=n;
5、遍历数组:
for(var i=0;i<arr.length;i++){
arr[i];//当前次元素
}
6、特殊点:如何释放一个引用类型:
要看清楚这个引用类型对象有几个变量名引用着,每个变量都要释放才能真的释放干净
7、*新知识点:
索引数组:下标都是数字组成的数组 - 默认
关联(hash)数组:下标是可以自定义的数组
为什么要自定义下标:索引数组的下标无具体意义,不便于我们查找
创建:2步
1、创建一个空数组:var arr=[];
2、添加自定义下标并且赋值:arr["自定义"]=值
访问:arr["自定义下标"];
遍历:把所有的元素都取出来执行 相同 或者 相似的操作
问题:不能使用for循环,因为length失效了,关联数组永远为0,而且下标也在是一个数字
解决:for in循环:
语法:for(var i in 数组名){
数组名[i]
}
无敌:不光可以遍历关联数组,也可以遍历索引数组
个人建议:索引数组依然使用for循环
关联数组只能使用for in循环
***JS中除了undefined和null不是一个对象,万物皆对象,而且一切对象的【底层都是hash数组】
hash数组的原理:
hash算法:将字符串交给hash算法,会得到一个尽量不重复的数字,但是字符串内容相同的,那么得到的数字一定也是相同的
添加元素:将自定义的下标交给hash算法,得到一个数字(地址值),把要保存的数据放到那个地址之中
获取元素:将指定的下标交给hash算法,得到一个和添加时完全相同的数字(地址值),得到这个地址值之中保存这的数据了
3、*****数组的API:函数:前辈们预定义的好的,但是只有数组可以使用的方法 1、数组 转为 字符串: var str=arr.join("自定义连接符");
特殊:
1、如果没有传入实参,则和toString/String,完全一样,默认由,分割
2、固定套路:2个
1、鄙视题:提供一个数组给你,让你无缝拼接数组里面的内容变为一个字符串
var arr=["h","e","l","l","o"," ","w","o","r","l","d"];
var str=arr.join("")
console.log(str);//"hello world";
2、开发中:将数组中的数据拼接为页面上的元素:初级版数据渲染
var cities=["北京","南京","西京","东京","重庆"];
var str="<option>"+cities.join("</option><option>")+"</option>";
sel.innerHTML=str;//innerHTML可以识别标签
实现:二级联动:4个重点
1、必须使用二维数组,而且二维数组的数据顺序一定要和一级的对应上
2、select专属事件:select.onchange:状态改变事件:选中项发生改变才会触发
3、select具有一个属性:this.selectedIndex;获取选中项的下标 - 只有select不需要自定义下标
4、其实绑定事件的部分就是函数名,也可以拿来调用
2、拼接数组:添加元素到的末尾的新方式 var newArr=arr.concat(值1,arr1...); 特殊: 1、此方法不修改原数组,只会返回一个新数组 2、此方法传参支持数组参数,并且会悄悄的打散这个数组,单独传入
3、截取子数组:从starti位置截取到endi+1位置的元素,组成一个新数组 var subArr=arr.slice(starti,endi+1) 特殊: 1、此方法不修改原数组,只会返回一个新数组 2、含头不含尾 3、第二实参可以省略:从starti截到末尾 第一实参也可以省略:从头截到尾 - 昨天按值传递(浅拷贝) 深拷贝:复制了一个副本给对方 4、支持负数参数,-1代表倒数第一个
这条线向上的3个API都不会修改原数组
这条线向上的所有API都会修改原数组
4、删除、插入、替换: 删除:var dels=arr.splice(starti,n);//从starti开始删除n个 特殊:此方法其实也有返回值,所有删除的元素组成的一个新数组
插入:arr.splice(starti,0,值1,...);//从starti开始删除0个,插入了新元素
特殊:原来starti位置的元素以及后续元素都会被向后移动
替换:var dels=arr.splice(starti,n,值1,...);
特殊:插入的个数和删除的个数可以随意
5、翻转数组:arr.reverse(); - 没用
Array API: 6、排序:两种方式: 1、鄙视题:冒泡排序:把数组中的每一个数字取出来,前一个和后一个进行比较,如果前一个>后一个,两者就要交换位置: 公式: var arr=[13,25,4,3675,12,23,3,215,2,1,42,4,65,473,2431,123]; for(var j=0;j<arr.length-1;j++){ for(var i=0;i<arr.length-(j+1);i++){ if(arr[i]>arr[i+1]){ var m=arr[i]; arr[i]=arr[i+1]; arr[i+1]=m; } } } console.log(arr);
2、正式开发中:数组API提供的排序
arr.sort();
特殊:1、默认按照字符串按位PK每个字符的unicode号排序
2、按照数字排序:
arr.sort(function(a,b){//回调函数:不需要我们程序员调用的函数:悄悄的带有循环,提供了两个形参:a是后一个数,b是前一个数
return a-b;
})
//return a-b:如果a>b,返回是一个正数
// 如果a<b,返回是一个负数
// 如果a==b,返回是一个0,sort根据你反复的结果,来判断两者要不要交换位置
3、降序排列:
arr.sort(function(a,b){//回调函数:不需要我们程序员调用的函数:悄悄的带有循环,提供了两个形参:a是后一个数,b是前一个数
return b-a;
})
强调:JS中只有数组可以排序,以后我们见到网页上任何具有排序功能的案例,底层一定都是一个数组
7、栈和队列:4个API:添加元素和删除元素的新方式
栈:一端封闭,只能从另一端进出的操作
开头进:arr.unshift(值1,...);
开头出:var first=arr.shift();//一次只能删掉一个,并且会返回删除的元素
缺点:每一次进出都会修改其他人的下标
结尾进:arr.push(值1,...);
结尾出:var last=arr.pop();//一次只能删掉一个,并且会返回删除的元素
优点:不会影响到其他元素的下标
队列:只能从一端进入,另一端出:
开头进:arr.unshift(值1,...);
结尾出:var last=arr.pop();//一次只能删掉一个,并且会返回删除的元素
结尾进:arr.push(值1,...);
开头出:var first=arr.shift();//一次只能删掉一个,并且会返回删除的元素
【只读】字符数组:字符串的任何API都不会修改原字符串,保存新字符串
1、*****String API:
1、转字符串:
作用:3个
1、字符串中如果出现了和字符串冲突的符号,可用\将其转义为原文
" '
2、特殊功能:
换行:\n
制表符:\t
3、*可以书写unicode号 表示一个字
\uXXXX
汉字的第一个字:4e00
汉字的最后一个字:9fa5
2、*转换大小写:【统一的】转为大写或小写,再比较,忽略大小写:- 验证码
大写:var newStr=str.toUpperCase();
小写:var newStr=str.toLowerCase();
3、获取字符串中指定位置的字符的ascii码
var ascii=str.charCodeAt(i);
通过ascii码转回原文
var 原文=String.fromCharCode(ascii);
4、*检索字符串:检查索引/下标:从starti位置开始找右侧的第一个关键字的下标
作用:判断有没有
var i=str/arr.indexOf("关键字",starti);
特殊:1、starti可以省略,如果省略则从0开始
2、返回值:找到了,返回第一个字符的下标
***没找到,返回-1,其实我们根本不关心下标是几,只关心下标是不是-1,-1代表没找到,不是-1代表找到了
3、数组也可以使用此方法
4、鄙视题:找到所有关键字的位置
var str="no zuo no die no can no bibi";
var i=-1;
while((i=str.indexOf("no",i+1))!=-1){
console.log("找到了:"+i);
}
5、拼接字符串:var newStr=str.concat(str1,str2...) 还不如 +运算
6、*截取字符串:3个
1、**var subStr=str/arr.slice(starti,endi+1);
2、var subStr=str.substring(starti,endi+1);//不支持负数参数
3、*var subStr=str.substr(starti,n);//截取的个数,不必考虑含头不含尾
7、*替换字符串:今天不屌,需要有了正则表达式才会牛逼
var newStr=str.replace("关键字"/正则表达式,"新内容");
8、*****切割/分割字符串:作用:str <=> arr
var arr=str.split("自定义切割符");
特殊:
1、切割符可以自定义,切割过后返回一个数组,数组中不再包含切割符
2、如果传入的切割符是一个"",每一个字符都会被切开
扩展:创建元素并且渲染页面 1、创建空标签 var elem=document.createElement("标签名");
2、设置必要的属性或事件
elem.属性名="属性值";
elem.on事件名=function(){函数体} - 事件都可以在创建时提前绑定上
3、创建好的元素渲染到DOM树上
父元素.appendChild(elem);