没有逻辑,想到啥写啥,觉得重要就写下来
重要!:查阅MDN
什么是MDN:Mozilla 开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及HTML5 应用的 API。
MDN网址: https://developer.mozilla.org/zh-CN/
文章目录
- 1. JavaScript的组成
- 2. JavaScript是运行在客户端(浏览器)的编程语言,是**解释型语言**、**动态语言**
- 3. JS的书写位置
- 4. **输入输出语法**
- 5. 变量允许不声明直接赋值,允许多次声明并赋值同名变量,不会报错,一个变量被多次赋值后,原有的值会被**覆盖**,变量值以最后一次赋值为准
- 6. 尽量不要使用name作为变量名,因为name在一些浏览器中有特殊含义
- 7. JavaScript是一种弱类型语言(动态语言),这意味着不用提前声明变量的类型,运行过程中类型会被自动确定。允许更该变量的数据类型。
- 8. 一些特殊数值
- 9. bool类型可以参与数值运算,true=1,false=0
- 10. undefined 和 null的区别
- 11. 数据类型转换
- 12. 三元表达式
- 13. 逻辑中断(逻辑运算符的短路)
- 14. switch case中,case与表达式的匹配必须是全等,即值和数据类型必须都一样
- 15. 数组
- 16. **函数**就是封装了一段可以被重复调用的代码块
- 17. JS的作用域:代码名字在某个范围内起作用和效果
- 18. 预解析(面试考点)
- 19. 对象
- 20. 内置对象
1. JavaScript的组成
ECMAScript:规定了js基础语法核心知识。比如:变量、分支语句、循环语句、对象等等
Web APIs :
DOM 操作文档,比如对页面元素进行移动、大小、添加删除等操作
BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等
2. JavaScript是运行在客户端(浏览器)的编程语言,是解释型语言、动态语言
3. JS的书写位置
可以书写在直接写在html文件里,用script标签包住,script标签写在</body>
上面(内部 JavaScript);也可以书写在代码写在以js文件里,通过script标签和src属性<script src='example.js'> </script>
,引入到html页面中(外部 JavaScript);也可以写在标签内部<button onclick='hello'>这是一个按钮标签</button>
(内联 JavaScript)
4. 输入输出语法
//输出
document.write('输出内容');//向body内输出内容
alert('输出内容');//页面弹出警告对话框
console.log('输出内容');//控制台输出
//输入
pronmpt('输入内容');//显示一个对话框,对话框中包含文字信息,用来提示用户输入文字
5. 变量允许不声明直接赋值,允许多次声明并赋值同名变量,不会报错,一个变量被多次赋值后,原有的值会被覆盖,变量值以最后一次赋值为准
var age=18;
var age=20;
console.log(age);//此时age=20;
6. 尽量不要使用name作为变量名,因为name在一些浏览器中有特殊含义
7. JavaScript是一种弱类型语言(动态语言),这意味着不用提前声明变量的类型,运行过程中类型会被自动确定。允许更该变量的数据类型。
var age=18;
age='十八';
console.log(age);//此时age的值是字符串‘十八’;
8. 一些特殊数值
console.log(Number.MAX_VALUE);//数字型最大值
console.log(Number.MAX_VALUE*2);//无穷大
console.log(-Number.MAX_VALUE*2);//无穷小
console.log('这是一个字符串'-100);//非数值NaN
isNaN 是否是非数字类型
console.log(isNaN(12));
console.log(isNaN('这是一个字符串'));
获取数据类型 typeof
var num=10;
console.log(typeof num);
console.log(typeof flag);
var variable=undefined;
console.log(typeof variable);
var timer=null;
console.log(typeof timer);
输入框prompt得到的数据类型为String
<script>
var age=prompt('请输入年龄');
console.log(age);
console.log(typeof age);
</script>
9. bool类型可以参与数值运算,true=1,false=0
var flag=true;
var flag1=false;
console.log(isNaN(flag));
console.log(flag+1);
console.log(flag1+1);
10. undefined 和 null的区别
var variable;
console.log(variable+'pink');
console.log(variable+1);
var space=null;
console.log(space+'pink');
console.log(space+1);
11. 数据类型转换
转换为字符串:
num.toString()
String(num)
加号拼接:num+‘’
<script>
var num=10;
console.log(typeof num);
var str=num.toString();
console.log(typeof str);
var str2=String(num);
console.log(typeof str2);
var str3=num+'';
console.log(typeof str3);
</script>
转换为数值型:
<script>
var num=parseInt('3.14');
console.log(num);
console.log(parseInt('120px'));//自动去单位
var num1=parseFloat('3.14');
console.log(num1);
var num3=Number('1.23');
console.log(num3);
var num4='12'-0;
console.log(num4);
var num5='12'*1;
console.log(num5);
</script>
转换为布尔型:
5种会转化为false的情况:
<script>
console.log(Boolean(''));
console.log(Boolean(0));
console.log(Boolean(NaN));
console.log(Boolean(null));
console.log(Boolean(undefined));
</script>
12. 三元表达式
条件表达式 ?表达式1:表达式2
如果条件表达式为真,则返回表达式1 的值,否则返回表达式2 的值。
13. 逻辑中断(逻辑运算符的短路)
短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行
逻辑与:如果表达式1 为真,则返回表达式2;如果表达式1为假,则返回表达式1
逻辑或:如果表达式1 为真,则返回表达式1;如果表达式1为假,则返回表达式2
console.log(123&&456);
console.log(0&&456);
console.log(''&&456);
console.log(123||456);
console.log(0||456);
14. switch case中,case与表达式的匹配必须是全等,即值和数据类型必须都一样
var num='3';
switch(num){
case 3:
console.log('ok');
break;
}
没有输出,表示匹配没有成功
15. 数组
创建数组:
var arr=new Array();//创建
var arr=[];//利用数组字面量创建数组
var arr2=[1,2,'hello',true];//数组里可以放任意数据类型
访问数组元素
通过下标访问,未初始化的元素会返回undefine
var arr2=[1,2,'hello',true];//数组里可以放任意数据类型
console.log(arr2);
console.log(arr2[2]);
console.log(arr[5]);
数组长度 arr.length
新增数组元素:
JS中,数组长度是可变的
通过修改length属性:
var arr=['red','green','blue'];
console.log(arr);
arr.length=5;
console.log(arr);
通过追加数组元素:
var arr=['red','green','blue'];
arr[3]='yellow';
console.log(arr);
16. 函数就是封装了一段可以被重复调用的代码块
//声明函数
function hello(){
console.log('HelloWorld');
}
//调用函数
hello();
声明函数时,不用写明参数的数据类型
function myFunc(aru){
console.log(aru);
}
myFunc('hello');
myFunc('world');
形参和实参个数可以不一致,如果实参个数多于形参,从前往后取到形参的个数为止;如果实参个数少于形参,未收到值的形参为undefined:
function getSum(num1,num2){
console.log(num2);
console.log(num1+num2);
}
getSum(1,2,3);//实参个数多于形参
getSum(1);//实参个数少于形参
函数的返回值: 在定义函数时不需要定义返回值的数据类型
arguments的使用:
argument是函数内置的对象,存储了传递的所有实参
arguments属于伪数组,什么是伪数组:具有数组的length属性,按照索引的方式进行存储,但没有真正数组的一些方法,如pop()、push()等
例1:
function fun(){
console.log(arguments);
console.log(arguments.length);
console.log(arguments[2]);
}
fun(1,2,3);
例2:利用arguments求任意多个数的最大值
function fun(){
var max=arguments[0];
for(var i=1;i<arguments.length;i++){
if(arguments[i]>max){
max=arguments[i];
}
}
return max;
}
console.log(fun(11,2,34,17,89,1,345));
例3:翻转数组
function reverse(arr){
var newArr=[];
for(var i=arr.length-1;i>=0;i--){
newArr[newArr.length]=arr[i];
}
return newArr;
}
console.log(reverse([1,3,4,6,9]));
例4:冒泡排序
function sort(arr){
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
}
var arr=[1,7,3,8,4,5];
console.log(sort(arr));
函数表达式(匿名函数):函数表达式的声明方式和函数类似,只不过变量里存的是值,函数表达式里存的是函数
调用方法:变量名()
函数表达式也可以传递参数
var fun=function(aru){
console.log('这是一个函数表达式');
console.log(aru);
}
fun('hello');//fun是变量名,不是函数名,
17. JS的作用域:代码名字在某个范围内起作用和效果
作用域详解参考资料:文章链接
JS的作用域(es6之前)分为:全局作用域;局部作用域
全局作用域:在整个script标签内 或者js文件内 都可见
局部作用域(函数作用域):只在某个函数内部起作用
变量的作用域:
根据作用域不同,变量可分为局部变量和全局变量
全局变量:在全作用域下的变量,定义在最外层的变量
局部变量:在局部作用域下的变量,定义在函数内部的变量
注意:在函数内部 没有声名直接赋值的变量也属于全局变量
函数的形参也可以看作局部变量
从执行效率来看:全局变量只有在浏览器关闭时才会销毁,比较占内存资源;局部变量当程序执行完毕就会销毁,比较节约内存资源。
var str1='全局变量';//全局变量
console.log(str1);
function fun(){
console.log(str1);
}
function fun1(){
var str2='局部变量';//函数的形参也可以看作局部变量
str3='未声明的变量';//在函数内部 没有声名直接赋值的变量也属于全局变量
}
fun1();//先执行一遍函数,否则会报错
console.log(str3);
console.log(aru);//错误
console.log(str2);//错误
作用域链:如果函数中还有函数,那么在这个作用域中又可以诞生一个新作用域。
根据内部函数可以访问外部函数变量的机制,用链式查找决定哪些数据能被访问,就称之为作用域链。
内部函数在访问外部函数变量时,采取链式查找的方式,一层一层往外查找(就近原则)
var num=10;
function fn(){
var num=20;
function fun(){
console.log(num);//输出结果为20
}
fun();
}
fn();
18. 预解析(面试考点)
JS运行代码分为两步:预解析和代码执行。在预解析时,JS引擎会把JS里所有的var和function提升到作用域最前面,然后再从上往下依次执行
预解析分为:变量预解析(变量提升)和函数预解析(函数提升)。变量提升会将所有变量声明提到当前作用域的最前面(不提升赋值操作) ;函数提升就是把所有的函数声明提升到当前作用域的最前面,但不调用。
console.log(num);//变量预解析
var num=10;
// 相当于以下代码:
// var num;
// console.log(num);
// num=10;
fn();//函数预解析
function fn(){
console.log(11);
}
// 相当于以下代码:
// function fn(){
// console.log(11);
// }
// fn();
fun();
var fun=function(){
console.log(22);
}
// 相当于以下代码:
// var fun;
// fun();
// fun=function(){
// console.log(22);
// }
例1:
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
// 相当于执行了以下操作
// var num;
// function fun() {
// var num;
// console.log(num);
// num = 20;
// }
// num = 10;
// fun();
输出结果:
例2:
// 案例2
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
// 相当于以下代码
// var num;
// function fn() {
// var num;
// console.log(num);
// num = 20;
// console.log(num);
// }
// num = 10;
// fn();
输出结果
例3:
// 案例3
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
// 相当于以下代码
// function f1() {
// var a;
// a = b = c = 9;
// // 相当于 var a = 9; b = 9; c = 9;
// b 和 c 直接赋值 没有var 声明 当 全局变量看
// // 集体声明 var a = 9, b = 9, c = 9;
// console.log(a);
// console.log(b);
// console.log(c);
// }
// f1();
// console.log(c);
// console.log(b);
// console.log(a);
运行结果:
关于预解析的详细讲解可以参考黑马的视频:视频链接
19. 对象
创建对象:
利用对象字面量创建对象: 属性和方法采用键值对的形式(属性名:值),多个属性或方法用逗号隔开,方法是以匿名函数的形式定义的
调用对象属性:对象名.属性名 或 对象名[‘属性名’]
调用对象方法:对象名.方法名()
var obj={};//创建一个空的对象
var obj={
uname:'张三',
age:23,
sayHi:function(){
console.log('Hi');
}
}
//使用对象
// 调用对象属性:
console.log(obj.uname);
console.log(obj['age']);
//调用对象方法
obj.sayHi();
new Object创建对象: 利用等号赋值的方法添加属性和方法,之间用分号隔开
var obj=new Object();//创建按一个空对象
obj.uname='张三';
obj.age=23;
obj.sayHi=function(){
console.log('hi');
}
console.log(obj.uname);
obj.sayHi();
利用构造函数创建对象:前两种创建方法一次只能创建一个对象,里面可能存在许多相同的属性和方法,利用构造函数可以重复相同的代码。
构造函数 :是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
在 js 中,使用构造函数要时要注意以下几点:
- 构造函数用于创建某一类对象,其首字母要大写
- 构造函数要和 new 一起使用才有意义
- 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
- 构造函数中不需要 return 返回结果。
构造函数的语法:
function 构造函数名(){
this.属性=值;
this.方法=function(){ }
}
调用:new 构造函数名();
function Star(uname,age,sex){
this.uname=uname;
this.age=age;
this.sex=sex;
this.sing=function(sang){
console.log(sang);
}
}
var ldh = new Star('刘德华',18,'男');//调用构造函数返回的是一个对象
console.log(typeof ldh);
console.log(ldh.uname);
ldh.sing('冰雨');
new 在执行时会做四件事情:
- 在内存中创建一个新的空对象。
- 让 this 指向这个新的对象。
- 执行构造函数里面的代码,给这个新对象添加属性和方法。
- 返回这个新对象(所以构造函数里面不需要return)。
⭐ 遍历对象:
for…in 语句用于对数组或者对象的属性进行循环操作。
其语法如下:
for (变量 in 对象名字) {
// 在此执行代码
}
var obj={
name:'张三',
age:18,
sex:'男'
}
for(var k in obj){
console.log(k);//输出属性名
console.log(obj[k]);//输出属性值
}
20. 内置对象
JavaScript内部提供的对象,包含各种属性和方法给开发者调用
- Math
三种取整方法:
Math.floor():向下取整,和小数接近且小于该小数的整数
Math.ceil():向上取整,和小数接近大于该小数的整数
Math.round():四舍五入
随机数:random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1
console.log(Math.random());//0到1之间的随机小数
// 得到两个数之间的随机整数(包含上下界)
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1))+min;
}
console.log(getRandom(1,10));
- Date日期对象的使用
Date() 是一个构造函数,必须通过new来调用日期对象
不传入参数:返回系统当前时间
参数常见写法:1.数字型 2022,8,19 ;2. 字符串型’2022-8-29 16:50:00’ 注意:数字型返回的月份会比传入的参数大1个月,如传入2022,8,19,返回的是2022年9月28日
var date=new Date();//不传参,返回当前时间
console.log(date);
// 参数常见写法:1.数字型 2022,8,19 2. 字符串型'2022-8-29 16:50:00'
var date1=new Date(2022,8,29);//返回的是9月,不是8月
console.log(date1);
var date2=new Date('2022-8-29 16:50:00');
console.log(date2);
日期格式化:
getMonth()返回值的范围为0~11,这意味这返回的月份会比实际的月份小一个月;getDate(),周日返回的是0
var date=new Date();//不传参,返回当前时间
console.log(date);
console.log(date.getFullYear());
console.log(date.getMonth()+1);//返回的月份小一个月
console.log(date.getDate());
console.log(date.getDay());//周日返回的是0
var year=date.getFullYear();
var month=date.getMonth()+1;
var dates=date.getDate();
var day=date.getDay();
var arr=['日','一','二','三','四','五','六'];
console.log('今天是:'+year+'年'+month+'月'+dates+'日,星期'+arr[day]);
var date=new Date();//不传参,返回当前时间
console.log(date);
console.log( date.getHours());
console.log(date.getMinutes());
console.log(date.getSeconds());
// 返回当前时分秒的函数:
console.log(getTime());
function getTime() {
var time=new Date();
var h=time.getHours();
h=h<10 ? '0'+h : h;
var m=time.getMinutes();
m=m<10 ? '0'+m : m;
var s=time.getSeconds();
s=s<10 ? '0'+s:s;
return h+':'+m+':'+s;
}
获取date总的毫秒数(时间戳),即距离1970-1-1过了多少毫秒数
//获取date总的毫秒数(时间戳) 距离1970-1-1过了多少毫秒数
var date=new Date();
console.log(date.valueOf());//方法1
console.log(date.getTime());//方法2
var date1=+new Date();//方法3
console.log(date1);
console.log(Date.now());//方法4
- 数组对象Array
创建数组:
// 利用字面量创建
var arr=[1,2,3];
//new Array()
var arr1=new Array();//创建一个空数组
var arr2=new Array(2);//创建一个新数组数组长度为2
var arr3=new Array(2,3);//数组里有两个元素 2,3 等价于[2,3]
检测是否为数组:
var arr=new Array(1,2,3);
var num=10;
// instanceof 运算符
console.log(arr instanceof Array);
console.log(num instanceof Array);
// isArray方法
console.log(Array.isArray(arr));
console.log(Array.isArray(num));
添加数组元素:
(1)push方法,在数组末尾添加一个或多个数组元素(追加),返回值是新数组长度,原数组会发生变化
(2)unshift 在数组开头添加元素,返回值是新数组长度,原数组会发生变化
// push方法,在数组末尾添加一个或多个数组元素(追加)
var arr=new Array(1,2,3);
console.log(arr.push(1,2,'a'));
console.log(arr);
// unshift 在数组开头添加元素
console.log( arr.unshift('red','green'));
console.log(arr);
删除数组元素:
(1) pop(), 删除数组最后一个元素,返回值是被删除的元素,原数组会变化
(2)shift(),删除数组第一个元素,返回值是被删除的元素,原数组会变化
var arr=new Array('red','green',1,2,3,);
// pop() 删除数组最后一个元素
console.log(arr.pop());
console.log(arr);
console.log(arr.shift());
console.log(arr);
筛选数组:
var arr = [1500, 1200, 2000, 2100, 1800];
var newArr=[];
for(var i=0;i<arr.length;i++){
if(arr[i]<2000){
newArr.push(arr[i]);
}
}
console.log(newArr);
⭐⭐ 数组排序:
(1)reverse(),翻转数组,会改变原数组,返回新数组
(1)sort(),数组排序,会改变原数组,返回新数组
var arr=[1,2,3];
console.log(arr.reverse());//翻转数组
var arr1=[2,4,1,5];
console.log(arr1.sort());//数组排序
var arr2=[1,33,17,77,7];
console.log(arr2.sort());//s输出结果有误
arr2.sort(function(a,b){
return a-b;
});//解决方法,升序排列
console.log(arr2);
arr2.sort(function(a,b){
return b-a;
})
console.log(arr2);
数组索引方法:
var arr=['red','green','blue','yellow','blue'];//只返回第一个满足条件的左引号
console.log(arr.indexOf('blue'));
console.log(arr.indexOf('white'));//如果找不到就返回-1
console.log(arr.lastIndexOf('blue'));//返回最后一个索引号
⭐⭐数组去重:
① 目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重。
② 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,我们就添加,否则不添加。
③ 我们怎么知道该元素没有存在? 利用 新数组.indexOf(数组元素) 如果返回时 -1 就说明 新数组里面没有改元素
var arr=['c','a','z','a','x','a','x','c','b'];
function unique(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i])==-1){
newArr.push(arr[i]);
}
}
return newArr;
}
var demo=unique(arr);
console.log(demo);
数组转化为字符串:
var arr=[1,2,3];
console.log(arr.toString());
//join(分隔符)
console.log(arr1.join());//默认为逗号
console.log(arr1.join('&'));
- 字符串
基本包装类型:
字符串的不可变:指的是字符串里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。如:
var str = 'abc';
str = 'hello';
当重新给 str 赋值的时候,常量’abc’不会被修改,依然在内存中。重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变。
由于字符串的不可变,在大量拼接字符串的时候会有效率问题,应当避免大量拼接字符串。
因为字符串不可变,所以字符串的所有方法都不会修改字符串本身,操作完成会返回一个新的字符串。
根据字符返回位置:
var str='改革春风吹满地,春天来了';
console.log(str.indexOf('春'));
console.log(str.indexOf('春',3));//从索引3的位置往后查找
⭐ 根据位置返回字符:
charCodAt 返回指定位置字符的ASCII码,目的:判断用户按下了哪个键
// 1. charAt(index) 根据位置返回字符
var str='Hello';
console.log(str.charAt(3));
// 遍历字符
for(var i=0;i<str.length;i++){
console.log(str.charAt(i));
}
//2. charCodAt 返回ASCII码,目的:判断用户按下了哪个键
console.log(str.charCodeAt(0));
// 3. str[index]
console.log(str[0]);
字符串操作方法:
// 1.拼接字符串 concat
var str1='a';
console.log(str1.concat('bc'));
//substr('起始位置','截取几个字符')
var str='Hello world!';
console.log(str.substr(3,6));
// 替换字符串 replace('被替换字符','替换为的字符’)
var str2='attach';
console.log(str.replace('a','b'));//只替换第一个
var str3= 'abcoefoxyozzopp';//替换掉所有的o
while(str3.indexOf('o')!=-1){
str3=str3.replace('o','*');
}
console.log(str3);
//字符串转化为数组 split('分隔符')
var str4='red&blue&green';
console.log(str4.split('&'));