ITPub博客

首页 > IT职业 > IT图书 > JavaScript终极BOSS,函数

JavaScript终极BOSS,函数

IT图书 作者:samenzhou 时间:2021-09-09 09:43:06 0 删除 编辑

你确定掌握了JS的函数,真的确定吗?

警告:最后一站:秋名山,座下乃AE86,无法保证不撒豆腐,路途颠簸刺激,请务必拉好扶手!

js arguments

比如你要做个平方处理,弄个函数如下:

function getSquare(num) {
    return num * num // 当然可以使用Math方法,这里不提。
}

let result = getSquare(987)
console.log(result) // 974169

又或者如下:

let initialNum = 987

function makeSquare() {
    initialNum *= initialNum 
}

makeSquare()
console.log(initialNum) // 974169

这两个函数使用相信大家没什么问题,主要说明一下里面的return区别。

第一个提供的是公共函数,就是你给我一个数,我帮你给平方并且把结果返回给你,所以需要return。

第二种是对已经有的数据处理,并不产生新的需要用到的变量,所以就不需要返回,也就不需要return。

不写return还是会默认返回一个值,其实JS操作都会返回一个值,即return一个值出来,如果是没有明确return什么东西,则返回的是undefined。

上述例子改写一下,如下:

let result = getSquare(987)

function getSquare(num) {
    return num * num // 当然可以使用Math方法,这里不提。
}

console.log(result) // 974169

这种情况下没有报错,按说getSquare在使用后声明,应该会报错才是,但实际上不是,这里就有一个小知识点:函数的声明提升。实际代码解释后如下:

// 注意实际上被解释器提升到这里了。
let getSquare
getSquare = function(num) {
    return num * num // 当然可以使用Math方法,这里不提。
}

let result
result = getSquare(987)

console.log(result) // 974169

上面看不懂的请回去看我之前的文章:JavaScript变量。

这里要记住一点:具名函数是JS所有类型中的一等公民,所有提升函数都会到当前作用域的最上面!

this内容在后面的ES6箭头函数那里

匿名函数

function(参数(可选)) {
    内容
    return x // return 可选
}

匿名函数由于没有名字,定义后续无法使用,因为无名所以找不到。正因此,匿名函数多用来作为回调。如下:

// 函数func1有一个参数any,any由于会执行,所以是个函数,因为这里给这个函数名字了,所以传进来时候不需要名字,即匿名。
function func1(any) {
    console.log('func1调用了')
    any()
}

// 执行func1并传了一个匿名函数进去
func1(function() {
    console.log('匿名函数调用了')
})

// func1调用了
// 匿名函数调用了

函数表达式

let func1 = function(参数(可选)) {
    内容
    return x // return 可选
}

与具名函数几乎一样,唯一区别就是无法做到完全的函数声明提升,此时不是具名函数也就不是一等公民了,如下:

let result = getSquare(987)

let getSquare = function(num) {
    return num * num // 当然可以使用Math方法,这里不提。
}

console.log(result) // Uncaught ReferenceError: getSquare is not defined,未定义。

解释器是这么玩的:

let result
result = getSquare(987)
let getSquare
getSquare = function(num) {
    return num * num // 当然可以使用Math方法,这里不提。
}
console.log(result)

看明白为什么报没有定义的错误了吧。


JavaScript判断语句

再者,有没有发现没有return还是实现了return的功能?result打印居然不是undefined?这就是箭头函数的一个return功能点:单句的情况下,并且没有大括号包裹,默认返回此单句

let af = num => {
    let a = 1
    let b = 2
    a + b
    num * num
}

let result = af(4)
console.log(result) // undefined,如你所愿。

af = num => {
    num * num
}

result = af(4)
console.log(result) // undefined,未能如你所愿。。。

个人倒是很喜欢这个不要括号的风格,与本尊爱的CoffeeScript又进了一步。

this

this对于函数来说,就是调用者。比如:a.func1() 那么原来func1里面的this都是a。如果是func1()这种调用,则是当前作用域this,比如全局下调用,当前this是window,所以func1里面的this也是window。因为相当于window.func1()。

具体this的相关如call,apply,bind以及new模式的this绑定。

但是箭头函数对此有特殊情况,具体区别见如下代码:

let obj1 = {
    func1: function() {
        console.log(this)
        let obj2 = {
            func2: function() {
                console.log(this)
            },
            af2: () => console.log(this)
        }
        obj2.func2()
        obj2.af2()
    },
    af1: () => console.log(this)
}

obj1.func1()
// obj1,谁调用this指向谁。
// obj2,谁调用this指向谁。
// obj1,自身不绑定this,this指向最近的被绑定this,若无,则Window。

obj1.af1() // Window,自身不绑定this,this指向最近的被绑定this,若无,则Window。

注意上述的代码与注释,说明了箭头函数与function函数this区别。


强制this绑定

与箭头函数无关

  1. call

  2. apply

  3. bind

call与apply

两者功能一致,都是强制绑定一个对象给函数调用,使得函数的this指向该对象,区别见表:

名称 区别
call x.call(obj, 参数1, 参数2, ...)
apply x.apply(obj, [参数1, 参数2, ...])
let obj = {
    func: function(num) {
        console.log(this)
        console.log(num)
    }
}

obj.func(1) // obj, 1

let objX = {
    x: 'x'
}

obj.func.call(objX, 2) // objX, 2
obj.func.apply(objX, [2]) // objX, 2

就是call可以正常传参,而apply把参数组成数组传进去,个人比较喜欢call。

bind

call与apply使用后会直接运行,而bind使用后会复制一个已绑定的对象函数,然后需要手动运行,传参与call一致。

let obj = {
    func: function(num) {
        console.log(this)
        console.log(num)
    }
}

obj.func(1) // obj, 1

let objX = {
    x: 'x'
}

let newFunc = obj.func.bind(objX, 2)
newFunc()

可以获取一个随时使用的被绑定指定对象的函数,优先考虑使用。

new

没什么太多可说的,秉承着谁调用this指向谁就对了。

function Obj() {
    this.a = 1
    this.func = function() {
        console.log(this.a)
    }
}

let obj = new Obj()
obj.a // 1
obj.func() // 1

new的this指向优先级高于其他,心里有个数就好。


闭包

获取与使用原本应该拿不到的局部作用域内的引用或变量。

一例胜千言:

// 常规
function add() {
    let num = 1
    num++
    return num
}

add() // 2,调用的时候会新生成一个num,然后用完销毁num。
add() // 2,一样
add() // 2,一样
// 闭包
function add() {
    let num = 1
    return function() {
        num++
        return num
    }
}

let result = add()
console.log(result)
// f() {
//     num++
// return num
// }
result() // 2,num
result() // 3,num

获取并操作本该获取不到的num(当前是全局作用域,而num是在add函数作用域)。


恩,关于函数的知识点就说到这里了,喜欢我的文章请记得关注一波啊,我会定期更新技术文章。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/912/viewspace-2806481/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-19

  • 博文量
    104
  • 访问量
    1057