1、三个输出一个输入
// 1
alert('你好!')
// 2
console.log('控制台输出...');
// 3
document.write('页面输出...')
// 4
prompt('请输入...')
2、变量命名规范
严格区分大小写;
不能以数字开头;
不能是关键字/保留字;
变量名必须有意义;
遵守驼峰命名法。
3、let、const与var的区别
let和const是ES6新增的声明变量的关键词,之前声明变量的关键词是var。
1.var定义的变量,可以预解析,提前调用的结果是undefined,而let、const定义的变量不能预解析,否则会报错。
2.var定义的变量,变量名称可以重复,效果是重复赋值,而let、const定义的变量不能重复,否则会报错。
3.var定义的变量作用域是全局/局部作用域,而let、const定义的变量如果在{}中则只能在{}中调用。
4.在循环语句中var定义的循环变量和使用let定义的循环变量,执行原理和执行效果不同。const定义的变量存储的数据数值不能改变,也就是const定义的变量,不能重复赋值。
4、javaScript数据类型
js的数据类型分为两种:原始类型(即基本数据类型)和对象类型(即引用数据类型)。
基本数据类型:undefined(未定义)、null(空的)、number(数字)、boolean(布尔值)、string(字符串)、Symbol(符号);
引用数据类型:object(对象)、array(数组)、function(函数)、date(时间)等。
5、检测数据类型的7种方法
1、typeof 检测一些基本的数据类型
2、A instanceof B 检测当前实例是否隶属于某个类
3、constructor 构造函数
4、hasOwnporperty 检测当前属性是否为对象的私有属性
5、is Array 判断是否为数组
6、valueOf 可以看到数据的原始值
7、Object.portotype.toString 原型方法
6、数据类型转换
Number():可以把任意值转换成数字,如果要转换的字符串中有不是数字的值,则会返回NaN
parseInt(string,radix):解析一个字符串并返回指定基数的十进制整数,radix是2-36之间的整数,表示被解析字符串的基数。
parseFloat(string):解析一个参数并返回一个浮点数
隐式转换:+ - * %
toString():转换为字符串,null,undefined不能调用
7、运算符
一元运算符
// 前置++
let i =3
console.log(++i + 8)
// 后置++
console.log(i++ + 9)
// 前置++是自身先加1再参与运算,后置++是先参与运算,后加1.到了另一边再加1
比较运算符
console.log(3>5); false
console.log(3>=3); true
console.log(2=='2'); true
console.log(3==='3'); false
console.log(3!==5); true
// NaN不等于任何值,包括他自身
逻辑运算符
// 见假即假
// console.log(true && true); true
// console.log(true && false); false
// console.log(3<5 && 6<2); false
// 见真即真
// console.log(true || false);true
// console.log(false || false);false
// console.log(3>5 || 4===4);true
// 取反 假即真 真即假
// console.log(!true);false
// console.log(!false);true
// console.log(3>5);false
三元运算符
// 条件 ? 条件为true执行代码 : 条件为false执行的代码
// 用户输入2个数,在控制台输出最大的数
let num1 = prompt('请输入第一个数')
let num2 = prompt('请输入第二个数')
// 取值操作
let max = num1 > num2 ? num1 : num2
console.log(`最大的数是${max}`);
8、if判断语句
单分支语句
true执行代码
false不执行代码
if (true){
alert('你真棒')
}
双分支语句
let year = prompt('请输入年份')
// 双分支语句
if(year % 4 === 0 && year % 100 !== 0 || year % 400 === 0){
alert('闰年')
}else{
alert('平年')
}
多分支语句
let score = +prompt('请输入成绩')
if(score > 90){
alert('国家栋梁')
}else if(score > 70){
alert('中')
}else if(score > 60){
alert('不赖')
}else{
alert('废材')
}
9、 switch语句
根据输入的年龄,弹窗用户喜欢的内容
let love = prompt('请输入您的年龄')
switch(love) {
case '10':
alert('女人')
break
case '20':
alert('少妇')
break
case '30':
alert('熟女')
break
case '40':
alert('萝莉')
break
default:
alert('肾虚了')
}
10、循环
循环有:for循环、while循环、do while循环。
for(起始值,终止条件,变化量){
重复执行的代码
}
while循环
// 变量的起始值
let jin =1
// i <= 3 终止条件
while(jin <= 3){
// 每循环一次,去看条件,条件为true,继续循环,条件为false,循环结束
document.write(`我是第${jin}次循环<br>`)
// 变量的变化值
jin++
}
for循环
// 输出1-100岁
for(let i = 1; i <= 10; i++){
document.write(`今年${i}岁了<br>`)
}
双层for循环
// 九九乘法表
for(let j = 1; j <= 9; j++){
// 里层循环控制每一行星星的个数
for(let i = 1; i <= j; i++){
// 规律是j和i是自增的,1,2,3,4.....9
document.write(`<span>${i} * ${j} = ${i*j}</span> `)
}
document.write('<br>')
}
跳过本次循环
for(let i = 1; i <= 5; i++){
if(i === 3){
continue // 跳过本次循环
}
document.write(`这是第${i}循环<br>`)
}
结束当前循环
for (let j = 1; j <= 5; j++){
if(j === 3){
break // 不再执行循环
}
console.log(`这是第${j}循环`);
}
11、数组常用方法
arr.push('pink') // 向数组的末尾添加新内容
arr.pop('pink') // 删除数组的最后一项
arr.unshift('blue') // 向数组首位添加新内容
arr.shift('blue') // 删除数组的第一项
slice()按照条件查找出其中的部分内容
arr.splice(1,1,'blook') //对数组进行增删改
const a = arr.join(" === ") // 用指定的分隔符将数组每一项拼接为字符串
const b = jin.concat(arr) // 用于连接两个或多个数组,返回的是一个新数组
let c = arr.indexOf('yewool') // 检测当前值在数组中第一次出现的位置索引
lastIndexOf()检测当前值在数组中最后一次出现的位置索引
incIudes()判断一个数组是否包含一个指定的值
arr.sort() // 对数组的元素进行排序(默认是从小到大来排序 并且是根据字符串来排序的)
arr.reverse() // 把数组倒过来排列
arr.forEach((value,index,arr) =>{}) // 循环遍历数组每一项;没有返回值,会改变原数组
const d = arr.map((value,index,arr)=>{}) // 同上;有返回值,不会改变原数组
const n = arr.filter((value,index,arr)=>{}) // 参数同上,作用过滤,不会改变原数组
// find()根据条件查找第一个满足条件的元素;
// find()和filter()的区别,就是一个返回第一个,另一个返回所有;
console.log([111,222,333,444].find(item => item %2 == 0));
console.log([111,222,333,444].filter(item => item %2 == 0));
// findIndex()根据条件查找第一个满足条件的元素的索引值
console.log([111,222,333,444,].findIndex(item => item %2 == 0));
// every() 是否每一项都满足条件;有一项不满足就返回false
console.log([111,222,333,444,].every(item => item %2 == 0));
// some()是否存在一项都满足条件
console.log([111,222,333,444,].some(item => item %2 == 0));
12、字符串常用方法
// substring(): 截取字符串
console.log('abcdef' .substr(1,3)); //截取多少个
console.log('abcdef' .substring(1,3)); //截取从哪里到哪里(包左不包右)
// startsWith(): 是否以某个字符串为开始
console.log('abcdef' .startsWith('abc'));
// endsWith(): s是否以某个字符串为结束
console.log('abcdef' .endsWith('def'));
// replace():替换
console.log('abcdef' .replace('cd','123'));
// match(): 匹配
console.log('abcdef' .match(/aaa/));
// 1.slice(开始索引,结束索引):截取字符串-数组也支持;
console.log('abcdef' .slice(1,3)); // 截取从哪里到哪里(包左不包右)
// 2.split():切割字符串为数组;
console.log('张三&李四&王五' .split('&'));
// 3.includes(): 是否包含某个字符串
console.log('abcdef' .includes('cd'));
// 4.toUpperCase(): 转换大写
console.log('abcdef' .toUpperCase());
// 5.toLowerCase(): 转换小写
console.log('abcdef' .toLowerCase());
// 6.indexOf():查询某个字符串在调用者字符串中的索引值
console.log('abcdef' .indexOf('cd'));
12、函数
函数的形参和实参
function hanshu(形参1,形参2) {
console.log();
}
// 调用函数的时候,实参会赋值给形参
hanshu(实参1,实参2)
函数表达式
// 匿名函数
let fn= function(){
console.log('土豆');
}
fn()
// 具名函数
function dog() {
console.log('西红柿');
}
dog()
13、内置对象
14、作用域与作用域链
作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问,作用域分为全局作用域和局部作用域。
全局作用域
在整个script或者一个js文件里定义的变量,就是全局作用域,函数内部也可以访问。
局部作用域
局部作用域分为函数作用域和块级作用域。
在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
在 JavaScript 中使用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。
作用域链
作用域链就是变量的逐级查找机制,遵循的原则就是就近原则
15、闭包
简单理解: 闭包 = 内层函数 + 外层函数的变量
作用:扩展局部变量的作用范围
16、变量提升与函数提升
通过var定义的变量,在定义语句之前就可以访问到;变量的声明会提升到函数的顶部,变量的赋值并不会,值为undefined。
通过function声明的函数,在之前就可以调用;函数[表达式]不会进行变量提升,只有函数声明形式才可以,值为函数定义对象。
17、arguments、剩余参数、展开运算符
arguments在JS中译作参数,只有在函数中才存在,是一个伪数组。
剩余参数和arguments类似,也是接收每一次调用函数的实参数组。剩余参数是一个真数组,可以接收所有,也可以接收一部分
扩展运算符/展开运算符,把一个数组中的内容,展开变成参数序列。剩余参数是把参数序列赋值给一个数组,而扩展运算符是把数组中元素展开变成参数序列让某个函数使用。
写到实参位置的...,就是展开运算符;写到形参位置的...就是剩余参数。
18、箭头函数
// 箭头函数和普通函数中的this不一样
// 所以有的时候使用箭头函数,有的时候使用匿名函数
// 1.箭头函数的基本语法
const fn1 = () => {
console.log('我是函数fn1');
}
//调用
fn1()
// 2.如果只有一个参数可以省略小括号
const fn2 = a => {
return a * a
}
console.log(fn2(3));
// 3.如果只有一行代码,不需要返回值,可以省略大括号
const fn3 = (a,b) => a + b
console.log(fn3(2,2));
// 4.返回的如果是一个对象类型,需要用 () 包裹
const fn4 = username => ({username:username})
console.log(fn4('张三'));
箭头函数与普通函数的区别:
1.箭头函数没有arguments,获取动态的箭头函数参数,只能使用剩余参数。
2.箭头函数没有自己的this,它的this是继承而来,所以箭头函数的this指向取决于父级环境。
19、数组解构和对象解构
数组解构就是把数组中的元素,取出来赋值给某一些变量。
对象解构类似数组的解构,只不过数组有序,对象无序。所以,解构对象的时候,要求变量和属性名一一对应;
两者的形参都有三个,分别是值/下标/当前数组
21、new做的四件事
1.new会帮我们开辟内存空间,装载新的实例
2.new会把这个构造函数中的this,指向实例对象;
3.new会帮我们执行构造函数,绑定属性和方法;
4.new会帮我们返回当前的实例对象;
22、实例成员和静态成员
// 实例成员就是实例对象拥有的属性和方法;
// 静态成员就是构造函数拥有的属性和方法
// 实例成员只能实例对象调用,定义到构造函数里面
// 静态成员只能构造函数调用,定义到构造函数上面
// 1.实例成员
function Student(uname,age){
this.uname = uname;
this.age = age;
this.sayHi = function(){
console.log('大家好!');
}
}
// 2.静态成员
Student.gender = '男';
Student.eat = function(){
console.log('吃的多,有力气!');
}
// 实例成员只能该实例对象调用
let s1 = new Student('张三',18);
console.log(s1.uname,s1.age,s1.sayHi);
console.log(s1.gender,s1.eat); // undefined
// 静态成员只能构造函数调用
console.log(Student.gender,Student.eat);
23、Object中三个静态方法
// object中三个静态成员
const obj = {name: '张三',age: 18, gender:'男'};
// 1.Object.keys() 获取对象中的所有属性组成的数组
let arr1 = Object.keys(obj);
console.log(arr1);
// 2.Object.values() 获取对象中的所有值组成的数组
let arr2 = Object.values(obj)
console.log(arr2);
// 3.Object.assign() 赋值对象中的各种属性
// o1里面和o2重复会被覆盖,没有重复的值,会保留
// o2不会受到影响,还是原值.
let o1 = {name: '李四',gender: '男'};
let o2 = {name: '张三',age: 18};
console.log(o1);
Object.assign(o1,o2)
console.log(o1);
console.log(o2);
25、伪数组转真数组
// 1.Array.from();静态方法
let divs = document.querySelectorAll('div');
console.log(divs);
let arr1 = Array.from(divs);
console.log(arr1);
// 2.展开运算符;
let arr2 = [...divs];
console.log(arr2);
27、保留两位小数
// 有时候要保留两位有效数字(四舍五入保留)
console.log((0.01*50) .toFixed(2));
console.log((100) .toFixed(2));
30、面向对象和面向过程
面向对象是让对象帮我们完成某个需求,面向过程是一步一步完成某个需求.
应用场景:大型和超大型项目(困难)用面向对象,简单小就用面向过程.
未来场景:我们程序员只是使用对象,不常封装对象
31、原型对象和对象原型以及原型链
原型对象prototype,对象原型_proto_。
32、forin与forof
1.(功能不同) forin是遍历数组下标,forof是遍历数组元素
2.(原型的属性) for-in会遍历原型中的属性,for-of不会
3.(数据类型) 遍历数组用for-of,遍历对象用for-in.
33、深拷贝与浅拷贝
深拷贝就是对象的值,无论简单还是复杂类型,拷贝完毕后,修改一个另一个都不会被影响。
浅拷贝可以解决对象赋值一个被修改另一个也同时被修改的问题。复杂类型,浅拷贝还是解决不了被修改的问题
34、递归
递归就是函数自己调用自己。
35、call、apply、bind
call、apply、bind都是用来改变this指向
36、防抖和节流
防抖和节流都是单位时间内,减少触发某个逻辑;
1.防抖, 单位时间内多次触发,以最后一次为准; (回城 - 取消 - 回城)
2.节流, 单位时间内多次触发,以第一次为基准; ( 技能冷却)