JS的组成
- ECMAScript
ECMAScript是由ECMA国际(原欧洲计算机制造商协会)进行标准化的一]编程语言, 这种语言在万维网上应用广
泛,它往往被称为JavaScript或JScript ,但实际上后两者是ECMAScript语言的实现和扩展。 - DOM-文档对象模型
文档对象模型( Document Object Model ,简称DOM) , 是W3C组织推荐的处理可扩展标记语言的标准编程接口。
通过DOM提供的接口可以对页面上的各种元素进行操作(大小位置、颜色等)。
3.BOM–
-浏览器对象模型
BOM (Browser Object Model ,简称BOM)是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行
互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
变量
本质:变量是程序在内存中申请的一块用来存放数据的空间。
var
如果使用关键字 var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域。举例说明:
var a = 1; //此处声明的变量a为全局变量
function foo(){
var a = 2;//此处声明的变量a为函数foo的局部变量
console.log(a);//2
}
foo();
console.log(a);//1
如果在声明变量时,省略 var 的话,该变量就会变成全局变量,如全局作用域中存在该变量,就会更新其值。如:
var a = 1; //此处声明的变量a为全局变量
function foo(){
a = 2;//此处的变量a也是全局变量
console.log(a);//2
}
foo();
console.log(a);//2
注意:var 声明的变量存在提升(hoisting)。
提升
提升是指无论 var 出现在一个作用域的哪个位置,这个声明都属于当前的整个作用域,在其中到处都可以访问到。注意只有变量声明才会提升,对变量赋值并不会提升。如下例所示:
console.log(a);//undefined
var a = 1;
该代码段跟下列代码段是一样的逻辑:
var a;
console.log(a);//undefined
a = 1;
而如果对未声明过的变量进行操作,就会报错
console.log(b);//假设b未声明过,Uncaught ReferenceError: b is not defined
let
let 声明的变量,具有如下几个特点:
let 声明的变量具有块作用域的特征。
在同一个块级作用域,不能重复声明变量。
let 声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)。
let a = 1;
console.log(a);//1
console.log(b);//Uncaught ReferenceError: b is not defined
let b = 2;
function foo(){
let a = 1;
let a = 2;//Uncaught SyntaxError: Identifier 'a' has already been declared
}
以下是一个经典的关于 var 和 let 的一个例子:
经典异步问题
当前输出10,10,10…(共十个),因为setTimeout是异步任务,会首先执行主任务。再执行异步任务。而i是全局变量。所以等异步任务执行的时候,i一直都是10;
for (var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
},100)
};
该代码运行后,会在控制台打印出10个10.若修改为:
使用let,let是区块变量,只能在大括号内有效,并不会向后传递。
for (let i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
},100)
};
则该代码运行后,就会在控制台打印出0-9.
const
const 声明方式,除了具有 let 的上述特点外,其还具备一个特点,即 const 定义的变量,一旦定义后,就不能修改,即 const 声明的为常量。
const a = 1;
console.log(a);//1
a = 2;
console.log(a);//Uncaught TypeError: Assignment to constant variable.
但是,并不是说 const 声明的变量其内部内容不可变,如:
const obj = {a:1,b:2};
console.log(obj.a);//1
obj.a = 3;
console.log(obj.a);//3
所以准确的说,是 const 声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。
方法
声明多个变量
var age=18
var name='zs'
var address='火影村落'
//可以这么写
var age=18, name='zs', address='火影'
总结
var 声明的变量属于函数作用域,let 和 const 声明的变量属于块级作用域;
var 存在变量提升现象,而 let 和 const 没有此类现象;
var 变量可以重复声明,而在同一个块级作用域,let 变量不能重新声明,const 变量不能修改。
数据类型
结论:JS的数据类型有8种。
- 在ES5的时候,我们认知的数据类型确实是 6种:Number、String、Boolean、undefined、object、Null。
- ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
- 谷歌67版本中还出现了一种 bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。
JS数据类型:JS的基本类型和引用类型有哪些呢?
基本类型(单类型):除Object。 String、Number、boolean、null、undefined。
引用类型(复杂类型):object。里面包含的 function、Array、Date。
JS数据类型:如何判断数据类型?
- typeof 操作符(通用:上面有内容有讲到)
- isNaN()判断时候为数字
- Array.isArray( ) 检验值是否为数组
- instanceof 操作符
typeof
let num = 123
console.log(typeof num);//number
isNaN() 判断是否为合法数字 is not a number 不是数字就返回true
let a = '123';
console.log(isNaN(a));//false
let b = 123;
console.log(isNaN(b));//false
var e = '哈哈哈哈'
console.log(isNaN(e));//true
instanceof 操作符
数组是对象 对象可不是数组
let a = [12, 13, 140]
console.log(a instanceof Array);//true
let b = { a: 10, b: 10 }
console.log(b instanceof Object);//true
console.log(b instanceof Array);//false
数据类型转换
其他数据类型转化为字符串
toString ( ) | String()| 字符串拼接
let a = true
console.log(a);//true 布尔
console.log(a.toString());//true 字符串
console.log(String(a));// true 字符串
隐式转换 一般是使用+运算符
隐式转换是我们在进行算数运算的时候, JS自动转换了数据类型
console.log(a + '');// true 字符串 利用其他基本数据类型+字符串 就会变成 字符串
console.log(a - '');//布尔
把数组转成本地字符串 toLocaleString()
let arr = [1, 2, 3, 4, 5, 6]
console.log(arr);//[1, 2, 3, 4, 5, 6]
console.log(arr.toLocaleString());//1,2,3,4,5,6
隐式转换|算数运算
字符串转化为数值
parseInt()字符串转数值 取整数 不会四舍五入
console.log(parseInt('3.94px'));//3 数值型 数字开头+其他 会去掉其他
console.log(parseInt('3.94'));//3 数值型
console.log(parseInt('rem3.94px'));//NaN
**parsefloat()字符串转数值 取浮点 小数 **
console.log(parseFloat('3.94px'));//3.94 数值型 会去掉单位
console.log(parseFloat('3.94'));//3.94 数值型
Number() 字符串转数值 取浮点 小数 后面不可以跟其他
console.log(Number('123px'));//NaN
console.log(Number('3.99'));//3.99
隐式转换/算数运算
隐式转换是我们在进行算数运算的时候, JS自动转换了数据类型
console.log('3.95'- 0)//数值 3.95
console.log('3.95'- '1')//数值 2.95
console.log('3.95' * '1')//数值 3.95
console.log('3.95' / '1')//数值 3.95
console.log('3.95'+ 0)//数值 3.950
console.log('395'+ 0)//数值 3950
转化为布尔值
代表空、否定的值会被转换为false,如"、0、NaN、null、 undefined
其余值都会被转换为true
console. log (Boolean('')); // false
console. log (Boolean(0)); // false
console. log (Boolean(NaN)); // false
console. log (Boolean(null)); // false
console. log (Boolean (undefined)); // false
console . log (Boolean('小白')); // true
console. log (Boolean(12)); // true
运算符
算数运算
console.1og(1 * 1); // 1
console.1og(1 / 1); // 1
//1.%取余
console.1og(4%2);//0
console.log(5 % 3); // 2
console .1og(3%5); // 3
// 2.浮点数算数运算里面会有问题
console.1og(0.1 + 0.2); // 0. 300000000000004
console.1og(0.07 * 100); // 7 .00000000000001 I
// 3.我们不能直接拿着浮点数来进行相比较是否相等
var num = 0.1 + 0.2;// 0. 300000000000004
console. log(num == 0.3); // false
递增递减
如果需要反复给数字变量添加或减去1 ,可以使用递增( ++ )和递减( - )运算符来完成。
在JavaScript中,递增( ++ )和递减( – )既可以放在变量前面,也可以放在变量后面。放在变量前面时,
我们可以称为前置递增(递减)运算符,放在变量后面时,我们可以称为后置递增(递减)运算符。
注意:递增和递减运算符必须和变量配合使用。
// 2.前置递增运算符
先自加 后返回值
++写在变量的前面
var age = 10;
++age;//类似于age=age+1
console.1og(age );// 11
2.后置递增运算符
num++后置递增,就是自加1 ,类似于num= num + 1 , 但是num+ +写起来更简单。
// 1.
前置自增和后置自增如果单独使用效果是样的
// 2.
后置自增口诀:先返回原值后自加1 有运算先运算在自加
var age = 10;
先返回原值10参与运算 输出20
console.1og(age++ + 10);//20
后自加1
console.1og(age);//11
比较运算
逻辑运算
逻辑中断|短路运算
如果第一个为真的 返回第二个的结果
如果第一个为假得 返回第一个结果 停止运算
&&
// 1.用我们的布尔值参与的逻辑运算
true && false == false
// 2. 123 && 456 是值或者是表达式参与逻辑运算?
// 3.逻辑与短路运算 如果表达式1结果为真则返回表达式2
console.log(123 && 456); //456
//反之
console.log(false && 456)//false
//数值0算假的
console.log(0 && 456)//0
//字符串空字符串算假的
console.log('' && 456)//''
undefinde 假的
nan 假的
null 假的
||
console.log(123 || 456); //123
console.log(0 || 456)//456
console.log(0 || null)//null
赋值运算
运算符优先级
运算符优先级练习
分析图内的运算符权重:一元预算符>算数运算符> 逻辑运算符(&&> ||) 分三次比较
false || true && true && true
false || true
true
分析图内的运算符权重:括号 > 算数 > 逻辑
true && true
true
流程控制
多分支语句- if else
// 2.执行思路如果表达式结果为真那么执行语句1 否则执行语句2
// 3.代码验证
var age = prompt( '请输入您的年龄:’);
if (age >= 18) {
alert( '我想带你去网吧偷耳机' );
} else {
alert('滚,回家做作业去 );
// 5. if里面的语句1和else 里面的语句2最终只能有个语句执行
2送
// 6.
else后面直接跟大括号
多分支语句-switch
// 1. switch 语句也是多分支语句也可以实现多选1
// 2.语法结构switch 转换、开关case小例子或者选项的意思
// 3.执行思路 利用我们的表达式的值和case后面的选项值相匹配如果匹配上,就执行该case里面的语句
//4.表达式需要 === case 如果 '3' !=== case 3 不会执行
switch (表达式) {
case value1:
执行语句1;
break | continue |return;
case value2:
执行语句2;
break;
default:
执行最后的语句;
}
var fruit = prompt('请输入水果')
switch (fruit) {
case '苹果': alert('您输入的是苹果')
break;
case '香蕉': alert('您输入的是香蕉')
break;
case '西红柿': alert('您输入的是西红柿')
break;
default: alert('输入的不对')
break;
}
if 和 switch的区别
switch语句和if else if语句的区别
①一般情况下,它们两个语句可以相互替换
②switch…case 语句通常处理case为比较确定值的情况,而f…e…语更如灵活,常用于范围判断(大于、
等于某个范围)
③switch 语句进行条件判断后直接执行到程序的条件语句,效率更高。而if else语句有几种条件,就得判断多少次。
④当分支比较少时, if else语句的执行效率比switch语句高。
⑤当分支比较多时, switch语句的执行效率比较高,而且结构更清晰。
循环结构
在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要重复执行某些语句
for循环
// 1.for重复执行某些代码, 通常跟计数有关系
//2.for语法结构
for (初始化变量;条件表达式;操作表达式) {
循环体
}
// 3.初始化变量就是用var声明的一个普通变量, 通常用于作为计数器使用
// 4.条件表达式就是用来决定每一次循环是否继续执行就是终止的条件
// 5.操作表达式是每次循环最后执行的代码经常用于我们计数器变量进行更新(递增或者递减)
利用字符串追加一行排列星星
for (var i = 0; i <= 5; i++) {
console.log('★');
}
6*★
我们需要利用字符串追加
var c = ''
for (var i = 0; i <= 5; i++) {
c += '★'
}
console.log(c);
★★★★★★
双重for循环-常复习
外层循环一次 里面循环3次
双重for循环
打印星星
var row = prompt('打印几行?')
var col = prompt('一行打印几个?')
var str = '';//用户字符串追加让星星在一行上排列
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
str = str + '★'//追加星星 为了让星星在一行上显示
}
str = str + '\n'
}
console.log(str);
★★★★★
★★★★★
★★★★★
★★★★★
★★★★★
var str = '';
for (var i = 1; i <= 10; i++) {
for (var j = i; j <= 10; j++) {
str += '★'
}
str += '\n'
}
console.log(str);
★★★★★★★★★★
★★★★★★★★★
★★★★★★★★
★★★★★★★
★★★★★★
★★★★★
★★★★
★★★
★★
★
99乘法表
var sum = ''
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= 9; j++) {
sum += i + '*' + j + '=' + (i * j)
}
sum += '\n'
}
console.log(sum)
99乘法表
var sum = ''
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
sum += i + '*' + j + '=' + (i * j) + ' '
}
sum += '\n'
}
console.log(sum);
while循环
do while循环
continue break
continue
当 i = 3 的时候 就会执行continue 此时 不回执行下面的log 而是跳转到i++继续循环
言简意赅 当i = 3 我就不执行下面的代码 跳过这次循环
for (var i = 1; i <= 6; i++) {
if (i == 3) {
continue
}
console.log(i);//1,2,4,5,6
}
break
i=3的时候 break结束循环
for (var i = 1; i <= 6; i++) {
if (i == 3) {
break
}
console.log(i);// 1,2
}
数组
数组的概念
数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。
创建数组的方式
var arr = new Array()//实例对象 创建一个空的数组对象
var arr = []//字面量
数组算法
数组求最大值最小值
循环遍历数组 建立一个空数组 判断 如果你比我大 那你就赋值给我
//声明一个保存最大元素的变量max。
//默认最大值可以取数组中的第一个元素。
//遍历这个数组工把里面每个数组元素和max相比较。
//如果这个数组元素大于max就把这个数组元素存到max里面,否则继续下一轮比较。
//最后输出这个max
var arr = [2, 6, 1, 77, 52, 25, 7]
var maxArr = arr[0]
var minArr = arr[0]
for (var i = 0; i < arr.length; i++) {
//arr[i]数组大于max 就把 这个大的值给max
maxArr < arr[i] ? maxArr = arr[i] : maxArr;
//max大于 arr吗? 小于就把 值赋值给 max
minArr > arr[i] ? minArr = arr[i] : minArr;
}
console.log(maxArr);
console.log(minArr);
//利用内置对象Math求一串数字的最大值 ,数组需展开使用(去掉括号)
var arr = [1, 5, 88, 77, 66, 55, 44, 99, 999]
console.log(...arr);//展开运算符 会把数组的方括号展开
console.log(Math.max(...arr));
数组筛选大于等于10的值
// 要求: 将数组[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中大于等于10的元素选出来, 放入新数组。
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
var newArr = []
for (var i = 0; i < arr.length; i++) {
//newArr.length默认是空数组 长度为0 每次递增 数组必须要有长度才可以累加值
arr[i] >= 10 ? newArr[newArr.length] = arr[i] : null
}
console.log(newArr);
//第二种方法
var arr1 = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
var newArr = []
arr1.forEach((item) => {
item >= 10 ? newArr.push(item) : null;
})
console.log(newArr);
//第三种方法
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
var newArr = []
var j = 0;
for(var i = 0 ; i < arr.length;i++){
if(arr[i] >= 0){
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
翻转数组
//第三种方法
// 要求: 将数组[1, 2, 3, 4, 5, 6, 7, 8]翻转
//定义一个空数组用于接收
//循环遍历数组 i设定为数组的最后一个索引(数组从0 开始 最后的索引值是length-1) 依次递减 把值赋予给新数组即可
//arr.length = 8 ; arr.length-1 = 就是我们最后的一个索引值 0,1,2,3,4,5,6,7
var newArr = []
var arr = [1, 2, 3, 4, 5, 6, 7, 8]
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i]
}
console.log(newArr);//8,7,6,5,4,3,2,1
console.log(arr.length);//7
//第二种方法
var arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr.reverse()
console.log(arr);//8,7,6,5,4,3,2,1
冒泡排序 数组排序
冒泡排序
**冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,依次比较两个元素如果他们的顺序错误就把他们交换过来。 走访数列的工作是重复地进行直到没有再需要交
换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢浮到数列的顶端。
**
var temp
let arr = [1, 2, 3, 99, 13, 4, 99, 6, 4, 7, 5555] //length = 11
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) { //第一次循环 i = 0 j= i+1 就可以看做是arr[0] > arr[] 比较 你大于我吗?
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
}
}
console.log(arr);
数组方法-数组的内置对象
join()让数组转换成字符串
// 第一种方法 声明一个空字符串和数组拼接 让他们在一行显示
var str = ''
var arr = ['red', 'yellow', 'blue', 'pink']
for (var i = 0; i < arr.length; i++) {
str += arr[i] + '|'
console.log(arr[i]);
}
console.log(str);//red|yellow|blue|pink|
var newArr = ['red', 'yellow', 'blue', 'pink']
const strArr = newArr.join('|',)
console.log(strArr);//red|yellow|blue|pink
push()数组后面添加元素
切记不要直接给数组赋值 这样只会替换 不会追加
var Arr = ['r', 'e', 'd']
Arr.push('666')
console.log(Arr);//(4) ["r", "e", "d", "666"]
var newArr = ['r', 'e', 'd']
newArr.length = 5
console.log(newArr);// ["r", "e", "d", empty × 2]
unshift数组前面添加元素
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
arr.unshift(999)
console.log(arr);//[999,2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
splice()切割 替换 添加数组
//splice(索引值,删除第一个,替换的值)
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
arr.splice(2, 1, 6666)
console.log(arr);//[2, 0, 6666, 1, 77, 0, 52, 0, 25, 7]
sort()数组排序
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
arr.sort()
console.log(arr);//[0, 0, 0, 1, 2, 25, 52, 6, 7, 77]
//上面的方式 只实现了个位数的排序 ; 需要封装一个函数才可以实现排序算法
function sortArray(a, b) {
return a - b
}
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
arr.sort(sortArray)
console.log(arr);// [0, 0, 0, 1, 2, 6, 7, 25, 52, 77]
//这样也行
let arr = [1, 2, 99, 13, 4, 99, 6, 4, 7,5555]
arr.sort((a, b) => {
//返回值如果是正值,大于零 两个数就进行交换,负值不交换,相等也不交换
return a - b
})
//此时的arr就是排序好了的数组
console.log(arr);
reverse()翻转数组
var arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr.reverse()
console.log(arr);//8,7,6,5,4,3,2,1
foeach()遍历数组 迭代
//筛选所有的偶数
var arr = [2, 4, 7, 66, 5, 99]
var newArr = []
arr.forEach((item) => {
item % 2 === 0 ? newArr.push(item) : item
})
console.log(newArr);
filter() 筛选数组 返回的是一个数组
//筛选所有的偶数
var arr = [2, 4, 7, 66, 5, 99]
var newArr = arr.filter((item) => {
return item % 2 == 0
})
console.log(newArr);
some()检测数组中的元素时候满足条件 返回布尔值
函数
函数形参和实参
return
//函数返回值注意事项
// 1. return终止函数
function getSum(num1, num2) {
return num1 + num2; // return 后面的代码不会被执行
alert( '我是不会被执行的哦! ')
console. log(getSum(1, 2));
// 2. return 只能返回一个值
function fn(num1, num2) {
return num1, num2; // 返回的结果是最后一个值 返回最后一个值num2
}
console.1og(fn(1, 2));
** break ,continue ,return的区别**
●break : 结束当前的循环体(如for. while )
●continue : 跳出本次循环,继续执行下次循环(如for. while )
●return : 不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码
arguments
什么是arguments
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中, arguments实际上是当前函数的一一个内置对象。所有函数都内置了一个arguments对象, arguments对象中存储了传递的
所有实参。
//arguments的作用就是 如果我们没有传形参 可以通过每一个函数都有的内置对象arguments 来获取实参数
//arguments的作用就是 如果我们没有传形参 可以通过每一个函数都有的内置对象arguments 来获取实参数
function max() {
console.log(arguments);//
console.log(arguments.length);//1
}
max([555, 26666, 99, 101, 67, 77])
// 如果形参不确定 可以利用arguments
//求数组中的最大值
function Max() {
var maxSum = []
for (var i = 0; i < arguments[0].length; i++) {
if (maxSum < arguments[0][i]) {
maxSum = arguments[0][i]
}
// console.log(arguments[0][i]);
}
return maxSum
}
console.log(Max([1, 2, 3]));
console.log(Max([1, 2, 3, 6, 8, 7, 9]));
冒泡排序分装数组
// 冒泡排序分装数组
function foo(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
}
}
return arr
}
console.log(foo([5, 66, 77, 1, 2, 5, 7, 89]));
函数调用另外一个函数
输出结果是 111 , 222 , fn2 fn1
判断是否是闰年
var year = prompt('请输入年份')
function runYear() {
if (isRunYears(year)) {
alert('是')
}
else {
alert('不是')
}
}
runYear()
function isRunYears(year) {
console.log(year);
var flag = false // 默认不是闰年
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true //是闰年
}
return flag
}
匿名函数 利用变量储存函数 -函数表达式
作用域
JavaScript作用域:就是代码名字在某个范围内起作用和效果
.从执行效率来看全局变量和局部变量
//(1)全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
// (2)局部变量当我们程序执行完毕就会销毁,比较节约内存资源
块级作用域
目前var声明的变量是没有块级作用域
let 和 const有块级作用域
作用域链接
口诀 站在 输出的位置 一层一层往外查找
结果 a=4 b=‘22’
预解析 作用域链接
预解析分为函数预解析 变量预解析
预解析
变量预解析
因为js在执行代码的时候 是把变量 提升到顶层作用域 但是不赋值
console. log(num);/ / undefined坑1|
var num =10;
就相当于以下代码
var num //把变量提升到顶层作用域 不赋值
console. log(num);
num = 10
匿名函数(其实就是变量)预解析 或 函数表达式
fun(); //报错
var fun = function() {
console .1og(22);
}
//相当于执行了以下代码
var fun;
//函数一调用 但是下面没有这个函数
fun()
//现在压根就没有这个函数了
fun = function() {
console .1og(22);
}
var fun = function() {
console .1og(22);
}
fun(); //不回报错
步骤如下
var fun
fun = function() {
console .1og(22);
}
fun()调用函数
函数预解析
fn();
function fn() {
console.log(11);
}
执行步骤如下
//会自动吧函数提升到顶层
function fn() {
console.log(11);
}
fn();
预解析-变量提升-函数提升 必考
fun()
console.log(c);
console.log(b);
console.log(a);
function fun() {
var a = b = c = 9
console.log(a);
console.log(b);
console.log(c);
}
//1.先把所有变量 与 函数提升到 顶层作用域
function fun() {
var a
a = 9; b = 9; c = 9 //注意! 只有a有var 其他都是 没有的 是全局变量
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
fun()
console.log(c);//9
console.log(b);//9
console.log(a);//undefined
对象
什么是对象?
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
为什么需要对象
创建对象的方式
●利用字面量创建对象
// 利用字面量的方式创建对象
//属性名字(键):属性值(值) 逗号隔开 冒号声明
var obj = {
name() {//方法
return '您好'
},
age: '18'
}
//调用
console.log(obj.name());//您好
console.log(obj['age']); //18
●利用new Object创建对象
//利用new Object 创建对象
//属性名.属性值 分号隔开 等号声明
var obj = new Object();
obj.uname = '张三';
obj.age = 18;
obj.saHai = function () {
return '您好'
}
//调用
console.log(obj.uname);//张三
console.log(obj.saHai());//您好```
利用构造函数创建对象 重点
为什么需要利用构造函数创建对象?
- //因为我们一次创建个对象,里面很多的属性和方法是大量相同的我们只能复制
- //因此我们可以利用函数的方法重复这些相同的代码我们就把这个函数称为构造函数
- //又因为这个函数不一样,里面封装的不是普通代码,而是对象
- //构造函数就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
构造函数要命名要大写开头
this指向的是 创建的是谁 指向的就是谁 创建的是刘德华 指向的就是ldh 创建张学友 this指向的就是张学友
function Star(uname, age, sex) {
//this.属性 = 形参
//this.方法 = 函数
this.name = uname
this.age = age
this.sex = sex
this.sing = function(song){//方法
console.log(song) //冰雨
return song
}
}
const ldh = new Star('您的', 18, '男')
console.log(ldh.name);//'您的'
console.log(ldh.age);//18
console.log(ldh['sex']);//男
console.log(ldh.sing('冰雨')); //冰雨
//new Star() //new 一个对象 返回值是构造函数里面储存的数据
console.log(new Star('您的', 18, '男').name);//'您的'
构造函数 与 对象的关系
对象方法 遍历对象
var obj = {
name: '吴彦祖',
age: '18',
max: 6666
}
for (key in obj) {
console.log(key + ':' + obj[key]);
}
// name: 吴彦祖
// age: 18
// max: 6666
内置对象
时间戳
求倒计时
修改添加对象
var obj = {
age: 18,
price: 1000,
name: '刘志坤'
}
// Object.defineProperty(obj, prop,descriptor {
Object.defineProperty(obj, 'age', {
value: 20
})
console.log(obj.age);//20
Object.defineProperty(obj, 'sex', {
value: '男',
writable: false//值未false 表示不允许修改这个属性 默认值是false
})
console.log(obj);
Object.defineProperty(obj, 'sex', {
value: '女',
// writable: false
})
console.log(obj);//报错无法读取这个原型
var obj = {
age: 18,
price: 1000,
name: '刘志坤'
}
Object.defineProperty(obj, 'sex', {
value: '男',//添加/修改属性
writable: false,//默认值 不允许修改
enumerable: false,//默认值 不允许遍历出来 枚举
configurable: false,//默认值 不允许被删除
})
console.log(obj);//对象中添加了男属性
console.log(Object.keys(obj));//遍历对象 sex这个键属性名
delete obj.sex//删除利用方法添加的sex 由于设置configurable不允许被删除
console.log(obj);//没变化
简单数据类型的包装过程
字符串的不可变 字符串不回覆盖原先地址 会新开辟内存空间
不要大量拼接字符串 会造成很大的压力
给字符串修改数值;看上去是修改了 但是实际上JS开辟了一个新的内存空间 让str指向它
查找字符串的索引号
//字符串对象 根据字符返回位置 str. indexOf( '要查找的字符',[起始的位置])
var str = '改革春风吹满地,春天来了';
console . log(str . indexOf('春'));//2
console. log(str . indexOf('春',3)); //从索引号是3的位置开始往后查找//8
根据位置返回字符
根据字符串 返回出现的次数重点
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i) //利用索引 返回 匹配索引的字符串
//为什么用a[''] 而不是a.* 因为 charAt 返回的是字符串
//此时每一个对象都已经有值了
if (obj[chars]) {
obj[chars]++
}
//由于什么的o对象是一个空对象;里面是没有 给对象的每一个值 赋值为1
else {
obj[chars] = 1 //这一步操作就是 输出的就是这样{a: 1, b: 1, c: 1, o: 1, e: 1, …}
}
}
console.log(obj);
var max = 0 //声明一个变量 保存最大值
var word = null
for (let k in obj) {
if (obj[k] > max) {
max = obj[k]
word = k
}
}
console.log('字符串最多的单词是' + word + '它的次数' + max);
// 对象利用方括号导读
var b = {
a: 999
}
b['c'] = 111 //给对象 利用数组方式添加值
// console.log(b['a']);//999 注意数组内必须是字符串包裹属性名
console.log('---利用数组方式添加的对象--------');
console.log(b); //{a: 999, c: 1}
字符串方法
替换字符串replace()
var str = 'abooooooooooocccoooccc';
//替换字符replace(' 被替换的字符’,' 替换为的字符) //这种方法只替换第一个字符
// console.log(str.replace('ab', 'cd')); //'cdooooooooooocccoooccc'
//可以利用indexOf加while循环 替换o
while (str.indexOf('o') != -1) {
str = str.replace('o', '*')
}
console.log(str);
字符串转换成数组split()
var str = 'abooooo';
//split() 字符串转换为数组 根据字符串的符号来拆分
console.log(str.split(''));//["a", "b", "o", "o", "o", "o", "o"]
var str1 = 'ab,oo,ooo';
console.log(str1.split(','));// ["ab", "oo", "ooo"]
字符串去除空格
简单数据类型&复杂数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做弓用类型。
●值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
string , number , boolean , undefined , null
●引用类型: 复杂数据类型,在存储时变量中存储的仅仅是地址(引用) ,因此叫做引用数据类型
通过new关键字创建的对象(系统对象、自定义对象) , 如Object. Array. Date等
//null特殊 如果有个变量打算储存对象 没想好放啥 就用null
var time = null
console.log( typeof time);//object
堆和栈
堆和栈
// 1.简单数据类型是存放在栈里面里面直接开辟一个空间存放的是值
//2.复杂数据类型首先在栈里面存放地址十六进制表示然后这个地址指向堆里面的数据
复杂数据类型的传参数 考点
API WEB API
API ( Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序
与开发人员基于某软件或硬件得以访问一组例程的能力,而又无雾访问源码,或理解内部工作机制的细节。
简单理解: API 是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。
DOM
DOM的增删改查
鼠标事件
键盘事件
事件冒泡
事件对象
window.addEventListener('click', (event) => {
console.log(event);
})
BOM
立即执行函数
scroll