Skip to content

函数和自定义属性

函数声明

javascript
function foo() {}
console.log(foo) //ƒ foo(){}

代码中functionvar let const一样,都是声明变量的关键字

具名和匿名函数

javascript
function foo() {} //具名函数
document.onclick = function() {} //匿名函数
  • 具名函数: 有函数名的函数,如上文的foo
  • 匿名函数: 没有函数名,通常触发执行或者立即执行

声明和定义表达式

javascript
function foo1() {} //函数声明
var foo2 = function() {} //函数表达式

两者的区别:

  • 函数声明是声明函数,类似于声明变量
  • 函数表达式是声明变量然后赋值操作,两者含义不一样

函数是 JavaScript 的一等公民

function声明的函数可以先在前文使用再在下文声明,但请不要这样。
最好使用let + 函数表达式的方式定义函数,这将在后面章节中再提。

函数执行

函数后面添加括号执行:

javascript
function foo() {
    console.log("foo执行了")
}
foo() //函数调用,执行,在控制台打印。。。函数执行默认返回undefined,同赋值操作
function() {
    console.log("匿名函数错误执行方法")
}() //此时会报错:
//需要将匿名函数用()包裹
(function() {
    console.log("匿名函数正确执行方式,也叫IIFE")
})(); //打印。。。

匿名函数执行需要将匿名函数用()包裹,包括但不限于:

javascript
(function() {
    ...
})() ! function() {
    ...
}() +
function() {
    ...
}() -
function() {
    ...
}()
~ function() {
    ...
}()

函数表达式立执行的方法:

javascript
var foo3 = (function() {})() //当前foo3是函数的return值

函数参数

在任何情况下,执行函数都会进行相同的操作(不考虑随机)。
我们需要在不同条件下执行函数有不同的结果,可以给函数传参:

javascript
function say(mood) {
    console.log(`我今天的心情很${mood}`)
}
say("好") //"我今天心情很好"
say("糟糕") //"我今天的心情很糟糕"
  • 实参: 实际存在的参数,在函数调用的时候填写
  • 形参: 相当于在本函数作用域内即花括号内声明的变量,在函数声明的位置填写

注意

形参相当于赋值了一份实参去参与函数执行
在之后章节里学习了引用类型的值类型的区别后可以回来看下面这个例子:

形参相当于在函数内直接赋值的变量,不会影响原实参。

即现在这个函数是一个纯函数。

javascript
foo1 = function(x) {
    x += 1
}
var x = 1
foo1(x) //内部先赋值 内部x = 外界x
console.log(x)

当参数是复杂对象的时候,赋值相当于别名。此时函数会影响原实参,不是纯函数了。

javascript
foo2 = function(o) {
    o.x += 1
}
var b = {
    x: 1,
}
foo2(b) //内部先赋值 内部o = 外部b
console.log(b.x)

默认参数

es6 的写法:

javascript
function foo(a = 0, b = 2) {
    console.log(a, b)
}
foo(1) //1 2
foo(undefined, 3) //0 3
//当有形参默认值的时候,且实参没写或者传入undefined时会使用默认值

es5 的惯用写法:

javascript
function foo(a, b) {
    a = a || 0
    b = b || 2
    console.log(a, b)
}

默认参数可以是其他形参构成的表达式

return 关键字

每次执行函数后会返回对应的值,用return关键字返回,是数学意义上的函数关系。

javascript
function foo1() {}
foo1() //undefined
function foo2() {
    return undefined
}
foo2() //undefined

函数执行完成之后会默认返回undefined
我们也可以主动返回undefined,但是返回了之后后续的代码就不会执行了。

javascript
var double = function(x) {
    console.log("double开始执行")
    return x * x
    console.log("返回了执行的结果")
}
double(3) //"double开始执行" 9

箭头函数

javascript
let fn = function(n) {
    return n + 1
}
fn(2) //3
let fn2 = (n) => n + 1
fn2(2) //3

箭头函数是函数表达式在 es6 的简单写法
默认返回箭头后面的表达式的计算结果。
多个参数时箭头前需要加小括号,
多个执行语句时箭头后面需要大括号括起来,
有大括号默认返回undefined需要手动指定返回。

javascript
let fn3 = (x, y) => {
    x += 3
    return x * y
}
fn3(1, 2) //8

单条语句直接加括号返回,特殊情况可以省略

javascript
let add = (a, b) => a + b
let reverse = (a) => -a

自定义对象属性

在 js 中对象相当于其他语言的 hashmap 类,而对象的属性(attr),相当于 hashmap 的一组键值对。

复杂对象都可以设置自定义属性,通过.访问属性或者[]访问键值

javascript
let fn = function() {}
fn.mood = "good!" //对象存在,设置属性不需要申明
let name = "mood"
console.log(fn.mood, fn["mood"], fn[name]) //"good!" "good!" "good!"

[]访问属性时属性名是字符串,可以是变量。
合法的对象属性:系统自带的属性: 比如window.alert; console.log等等

自定义标签属性

在标签内自定义的属性

html
<div class="box" ref="rt">
</div>
<script>
 let box = document.getElementsByClassName("box")[0]
  console.log(box.ref) //undefined
</script>

标签元素的自定义标签属性在 JS 环境里无法直接访问,也无法直接修改
有专门的访问修改的方法

javascript
//接上
box.getAttribute("ref") //"asd" 查找
box.setAttribute("ref", "dcd") //修改,增加
box.removeAttribute("ref") //删除

这是DOM(文档对象)自带的方法

注意

在新的 html5 规范中,自定义属性需要带上data-的前缀
使用.dataset等方法可以操作新规范下的属性,旧方法依然有效
在 jQuery 中分别使用.attr 和.data 方法来获取不同规范下的属性