JS函数,对象,数组
函数
概念:
- 函数就是一个内部封装了部分代码的盒子,可以在多个位置被调用
- 函数的使用
- 创建函数(定义函数)
- 调用函数
函数的定义
- 声明式定义
function fn() {
}
/**
* 分析:
* function:声明函数的关键字,代表接下来这段代码是一个函数
* fn:函数名,调用函数时需要使用,函数名自定义,符合命名规范和见名知意即可
* ():小括号内存放函数的参数
* {}:存放函数代码,调用函数时,想执行的代码都写在内部
*/
- 赋值式定义
var fn = function () {
}
- 声明式与赋值式的区别
- 书写区别
- 调用区别
// 声明式
fn1() // 可以执行
function fn1(){
// 函数代码
}
fn1() // 可以执行
//赋值式
fn2() // 不可以执行(相当于将一个函数赋值给一个变量,会有变量的声明提升,所以在变量声明前调用时,根据变量声明提升的规则,此时变量为 undefined ,所以不能被调用)
var fn2 = function () {
// 函数代码
}
fn2() // 可以执行
函数的调用
- 如果函数只定义不调用那么没有任何意义
- 不管是声明式还是赋值式定义的函数,调用方式都是一样的
- 调用语法: 函数名() / 变量名()
函数的参数
- 书写在function后的小括号内
- 参数的作用?
- 如果一个函数没有书写参数,那么这个函数的功能相对来说比较单一
- 如果书写了参数,能够使我们这个函数的使用更加灵活
- 参数的书写,分为两个
- 1.function后的小括号内 书写的参数我们叫做"形参"
- 形参的作用:书写之后,相当于在函数内部创建了一个变量,变量实际的值由"实参"传递
- 2.函数名后的小括号内 书写的参数我们叫做"实参"
- 实参的作用:将自身的值,按照一一对应的关系,传递给形参
function num () {
console.log(1 + 1)
}
num() // 打印值为 1+1
function num (a, b) { // 此处 a b 为形参
console.log(a + b)
}
num(1, 1) // 此处为 实参,分别传递给 a 和 b
num(1, 2) // 此处打印值为 1 + 2
- 形参和实参 两个的数量,要一一对应
- 1.形参的数量如果大于实参:会将实参按照顺序一一传递给对应的形参;多出来的形参,相当于变量只定义没赋值,所以他们的值是undefined
- 2.实参的数量如果大于形参:会将实参按照顺序一一传递给对应的形参,多出来的实参无法在函数内部通过参数的方式调用
// 少传参数
function num1(a, b, c, d) {
console.log(a,b,c,d)
}
num1(1, 2, 3, 4) // 打印1,2,3,4
num1(1, 2, 4) // 打印1,2,4,undefined
num1(4) // 打印4,undefined,undefined,undefined
// 多传参数
function num2 (a) {
console.log(a)
}
num2(1, 2) // 打印 1
num2(1) // 打印 1
函数的返回值
- 函数内部默认有一个 return 他的值就是函数的返回值,如果函数内部不写 return 那么函数默认在函数体内部最底部返回一个 undefined
- 如果不想返回 undefined 需要手动在函数内部写上 return 并且跟上需要返回的值
- 可以中断函数
函数的预解析
- JS在执行代码的时候,会有一个所谓的解析阶段
- 解析阶段,做了一件事,就是函数提升,就是将声明式函数的定义,提升到当前作用域的最顶端
作用域
- 什么是作用域? 就是变量可以起作用的范围
- 作用域分为两个:
- 1.全局作用域(直接在script内书写的代码)
- 在此作用域创建的变量,我们叫做全局变量,在当前script标签内的哪里都能使用
- 在JS中,全局作用域中有一个提前给我们准备好的 对象,这个对象叫做 window,我们创建的全局变量,会被自动添加到window对象中
- 2.局部作用域(在JS中,只有函数能够创建局部作用域)
- 在此作用域创建的变量,只能在当前作用域使用,超出这个作用域(也就是在函数外边)去使用,就会找不到变量
function fn(){
var sum = '我是在函数内部创建的文件,我是局部变量,所以我只能在当前函数内使用'
var abc123 = '我实在fn函数内部创建的局部变量'
console.log(sum)
}
fn()
// console.log(sum)//这里因为超出了这个变量的使用区间,所以会报错
var abc = '我是一个全局变量abc'//创建一个全局变量abc
console.log(window)
作用域链
作用域链就是在访问一个变量的时候,如果当前作用域内没有
会去自己的父级作用域,也就是上一层作用域内查找,如果找到就直接使用,如果没有找到继续向上层查找
直到查找到 最顶层的全局作用域,如果找到了直接使用,如果没有找到 报错提示变量不存在(未定义)
我们将这个一层一层向上查找的规律,叫做作用域链
作用域链的赋值规则:
在给变量赋值的时候,首先会去当前作用域内查找该变量,如果有,直接赋值,并停止查找;
如果没有,会去自己的父级查找,在父级找到直接修改然后停止查找,如果没有继续向自己的父级查找,直到找到全局作用域
在全局作用域内,找到直接赋值修改他的值,如果没有找到,那么会在全局作用域创建一个变量,并赋值
递归函数
- 什么是递归?
- 在编程世界中,递归就是一个自己调用自己的手段
- 递归函数:在一个函数内部,调用了自己,循环往复
- 其实递归函数和循环很类似
- 需要有初始化,自增,执行代码,条件判断
- 如果没有就会是一个没有尽头的递归函数,我们通常叫这种为 死递归
对象
- 什么是对象
- JS中的一种数据格式, 对象在JS中的数据类型 为: 引用数据类型(也有人喜欢叫 复杂数据类型)
创建对象
- 创建对象分为两种方式:
- 1.字面量的形式: var obj = {键值对}
- 2.内置构造函数的创建
- 语法1:var obj1 = new Object()
- 语法2:var obj1 = new Object({a:1,b:2})//创建一个具有属性或者说具有键值对的对象
- 注意:new Object 的O是大写的,不是小写
对象的操作(增删改查)
- 点语法
var obj = {
a:1,
b:'qwer',
c:true
}
console.log('原始对象:',obj)
//1.点语法---查询 获取到对象内部某一个属性对应的属性值
console.log(obj.a) // 1
console.log(obj.b) //qwer
//2.点语法---新增 向对象内部新增一个属性
obj.q = 'gg001'
obj.w = '23'
console.log('最新的对象:',obj)
//3.点语法---修改 修改对象内部某一个属性对应的属性值
obj.c = false
obj.b = 'false'
console.log('修改属性后的对象:',obj)
//4.点语法---删除 删除对象内部的某一个属性
delete obj.a
console.log('删除属性后的对象:',obj)
- 中括号语法
//5.中括号语法---查询
console.log(obj['a']) //1
console.log(obj['c']) //true
//6.中括号语法---新增
obj['w'] = 111
console.log('新增后的obj:',obj)
//7.中括号语法---修改
obj['a'] = 111
console.log('修改后的obj:',obj)
//7.中括号语法---删除
delete obj['a']
console.log('删除属性后的obj:',obj)
- 两种操作语法的差别
- 一般大部分情况下,点语法与中括号语法,作用相同,怎么选择都可以
- 特殊情况下我们需要使用中括号语法
- 1.对象的属性名,有纯数字或者特殊符号,这个时候,就只能使用中括号语法
- 2.如果涉及变量相关的时候,也需要使用中括号
//特殊情况1
var obj = {
100:'我的属性名是 纯数字100',
'!':'我的属性名是 特殊符号!',
'@':'我的属性名是 特殊符号@'
}
//此时不能使用点语法,可以使用中括号语法
// console.log(obj.100)
console.log(obj['100'])
console.log(obj[100])
// console.log(obj[!])//有问题,需要将特殊符号用引号包裹
console.log(obj['!'])
console.log(obj['@'])
//特殊情况2
var obj = {
a:1,
b:2,
name:'gg'
}
var myName = 'name'
// console.log(obj.myName) //undefined
console.log(obj[myName]) //'gg'
/**
* 中括号语法,内部书写的字符,如果不加引号,会把它当成变量去使用,所以找到实际的值之后,myName 这个变量对应的值为'name'
* 所以obj[myName] 相当于写了obj['name']
* 所以会去对象obj中找一个叫做name的属性名,找到之后打印在页面
*/
for ...in循环遍历对象
- "遍历对象" 想办法拿到对象内部所有的属性名与属性值
- 语法:for(var i in 要遍历的对象){循环要执行的代码}
for(var i in obj){
// console.log(i) // a q t u 这四个是对象obj的所有属性名/键名/key
//需求:打印对象的所有属性值
// console.log(obj.i) //undefined 点语法会将后边的字符当成字符串来使用,而不是当成变量,如果想当变量使用,那么使用中括号语法
console.log(obj[i]) //该对象的所有属性值
}
数组
- 什么是数组
- 数组字面意思就是存放数字的一个组合, 但这么说太过于片面, 更完善的说法应该是 `数组是存放一些数据的集合
- 简单来说我们把数据放到一个盒子中, 这个盒子就是数组, 注意数字内的数据是有顺序的
创建数组
-
字面量的方式
语法:var arr = [1,2,3,'q','w','e']
//1.字面量的方式
var arr = [1,2,3,'q','w','e']
console.log(arr)
-
内置构造函数的方式
语法1:var arr = new Array() 创建一个空数组 语法2:var arr = new Array(5) 创建一个有长度的数组 语法3:var arr = new Array(1,2,3) 创建一个有内容的数组
//2.内置构造函数的方式
//2.1创建一个空数组
var arr1 = new Array()
console.log(arr1)
//2.2创建一个有长度的数组
var arr2 = new Array(5)
console.log(arr2)
//2.3创建一个有内容的数组
var arr3 = new Array(1,2,3,'q','w','e')
console.log(arr3)
数组的 length 属性
length 就是长度的意思, 代表数组内有多少个成员(数据)
var arr = [1, 2, 3]
console.log(arr.length) // 3
数组的 索引 概念
- 索引也叫做下标, 就是指一个数据在这个数组内排列在第几个位置上
- 注意: 在所有的语言中, 索引(下标)都是从0开始的
数组的基本操作案例(冒泡,选择)
- 冒泡排序
var arr = [9, 6, 3, 1, 4, 7, 8, 2, 5];
for(i = 0; i < arr.length - 1; i
++){
for(j = 0; j < arr.length - 1 - i; j++){
if(arr[j] > arr[j + 1]){
var temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
- 选择排序
var arr = [9, 6, 3, 1, 4, 7, 8, 2, 5];
for(j = 0; j < arr.length; j++){
var minIndex = j
for(i = j + 1; i < arr.length; i++){
if(arr[minIndex] > arr[i]){
minIndex = i
}
}
var temp = arr[j]
arr[j] = arr[minIndex]
arr[minIndex] = temp
}
转载自:https://juejin.cn/post/7193258619624751160