• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

javascript的函数,返回值,作用域和变量提升

武飞扬头像
无双幽梦
帮助1

写在最前面

hello大家好 我是27岁才转行前端的李治,最近在复习原生javascript的知识点,我会抽时间把复习的内容整理成新手笔记发布,因为时间原因可能一周只能发布一到两篇,但是因为已经学习过一遍,所以简单重温还能回想起来,期望可以对刚刚入行的同志们带来一点点帮助,可以持续关注我的分享

今天复习的是关于js中的函数function的最基本的用法和概念,还有返回值return,作用域以及变量提升的相关知识点

函数


就是封装了一段可以重复调用执行的代码块,通过这个代码块,可以实现大量代码的重复使用

使用函数有两个步骤:

  • 声明函数
  • 调用函数

声明函数的方式

使用关键字function

 //函数名遵循给变量起名的规则
        function 函数名(){
            //代码块
        }

自变量的方式

var 函数名 = function(){
  //代码块
}

表达式声明函数

起始就是把一个函数体赋值给一个变量,这个变量就是函数名

var  num = function(){
    console.log('表达式声明函数');
}
num()

调用函数的方式

在函数体后面,使用函数名加上小括号,实现函数的调用

function fn(){
    // 代码块
}
fn(); // 函数调用

简单调用

简单调用被称为直接调用,一般适用于没有返回值的函数,就相当于直接执行函数中的代码块

function fn(){
    console.log('简单调用');
}
fn(); // 调用

事件中调用

js是基于事件的模型
页面加载,用户点击,移动鼠标等等,都会产生事件,事件发生其实就是调用函数

// 事件中调用普通函数
btn.onclick = function(){
    fn();
}

// 行内js调用
<button id="btn" onclick="fn()">按钮</button>

通过链接调用

可以使用超链接调用函数

<a href="javascript:fn()">超链接</a>

但是为了防止超链接自带的点击功能和添加事件的点击功能相互冲突,在给超链接添加点击事件的时候,需要把超链接本身自带的点击功能取消掉

<a href="javascript:;">超链接</a>

参数

形参和实参

  • 实参---就是实际值,函数在调用时传入的值就是实参
  • 形参---形式上的参数,是一个代表性的单词或字母,函数在声明的时候,接收值的就是形参

形参是一个省略了var关键字的变量,被称为是一个特殊变量
变量的传值是一个一个地对应的

function fn(num, sum) { // 形参 num = 3  sum = 4
    console.log(num   sum);
}
fn(3, 4); // 实参
fn(30, 4); // 实参
fn(31, 4); // 实参
fn(32, 4); // 实参
fn(33, 4); // 实参
fn(34, 4); // 实参
fn(35, 4); // 实参
fn(36, 4); // 实参

当实参的个数 < 形参的个数

实参的个数少于形参,如果形参参与运算,会报错

function fn(num, sum, yum, tum) { // 形参 num = 3  sum = 4
    console.log(num   sum   yum   tum); // NaN
}
fn(3, 4, 5); // 实参

实参的个数 > 形参的个数

多余的实参的值会丢失

function fn(num, sum) { // 形参 num = 3  sum = 4
    console.log(num   sum );
}
fn(3, 4, 5); // 实参

一般在项目中,实参和形参最合理的个数是4-8个

arguments

arguments是一个类数组对象,包含着传入函数中的所有参数.arguments主要用途是保存函数参数
是实参的一组集合,是以数组的形式存在的

function foo(){
  console.log(arguments) // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
  console.log(arguments[1]) // 2
}
// 当传递的实参个数超过形参的个数的时候不会报错,所有的实参都会保存在arguments里
foo(1,2,3,4) 

注意:
arguments中存的是实参,而不会存形参

function foo(a,b = 2,c = 3){
  console.log(arguments) // [Arguments] { '0': 1 }
  console.log(b) //2
  console.log(c) //3
}
//只传了一个实参,那么arguments中就只有一个值
foo(1) 

callee属性

arguments对象有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数
arguments.callee实际上就是函数名

// 递归求n的阶乘
function foo(n) {
  if (n == 1) {
    return 1
  }
  return arguments.callee(n - 1) * n //arguments.callee 相当于函数名foo
}
console.log(foo(10));

length属性

arguments对象的length属性返回实参个数

function foo(){
  console.log(arguments.length) //5
}
foo(1,2,3,4,5) 

函数的封装

当代码大部分相同,把相同的保留一份,不同的变成参数

function fn(a) {
    var num = 0;
    for (var i = 0; i <= a; i  ) {
        num  = i
    }
    console.log(num);
}
fn(50)
fn(80)
fn(90)
fn(100)
//使用时只需要调用函数并写入实参即可

返回值-return

在函数的内部,计算完成的值如果需要在函数的外部使用,就需要使用return返回值 把这个值返回给函数本身,可以在函数外部定义一个变量来接受这个值

function fn(){
    var a = 100;
    return a
}
var a = fn() // 100这个值 返回给函数本身,并在函数外部赋值给变量 a 
console.log(a);

什么时候使用返回值?
函数内部的值需要在外部使用后展示,需要使用返回值

返回的类型

可以返回任何类型

 return {} // number string boolean null undefined object

返回值后面的代码会不会执行?

function fn(){
    console.log('今天天气好好啊');
    // return   // return后面没有返回的值,返回的结果是undefined 
    return  // 有阻断代码的作用
    console.log('小芳,今天约吗?'); // 因为在return后面 是不执行的
}
console.log(fn());

return有阻断代码的作用 ruturn后面的代码不会执行

获取非行间样式

//  获取非行间样式
//  el:元素
//  attr:属性
// el=div   attr='height'
function getStyle(el, attr) {
  if (window.getComputedStyle) {
    //标准浏览器
    return window.getComputedStyle(el)[attr]
  } else {
    //非标准浏览器
    return el.currentStyle[attr]
  }
}

var speed = getStyle(div, 'height')

作用域

ES5: 在ES5中,没有块级作用域

局部作用域

在JavaScript函数中声明的变量,会成为函数的局部变量
以函数的花括号为界,花括号的内部就是局部作用域,函数内部声明的变量在函数外部不能访问,

全局作用域

在script双标签之间声明的变量会成为全部变量
在函数外部声明的变量,在函数内部可以访问,在任何位置都可以使用

var a = 10; // 全局变量
function fn() {  // 全局函数
  var b = 20; // 局部变量 -- 只能在局部作用域内被访问
  console.log(a); // 局部作用域是可以访问全局作用域的变量和函数的

  return function num() { // 局部函数
    console.log(b);
  }
  // num()

  return 100
}
console.log(fn()); // fn() = 100

fn()()

注意下面的代码

function fn(){
    a = 10; // 没有var关键字声明的变量,在任何位置都是全局的  但是不建议使用
}
fn()
console.log(a); //

作用域链

作用域链是给函数向上查找变量提供的一种路线,或者理解为一种查找机制
在当前作用域内没有被声明的变量就是**自由变量,**自由变量会顺着作用域向上查找,如果上一层没有找到,会一层一层的向上查找,直到找到全局作用域还没找到就会宣布放弃
这种一层一层的关系,就是作用域链

var a = 1;
function fn() {
    var b = 2
    function num() {
        var c = 3
        function sum() {
            var d = 4
            console.log(a); // 1 是自由变量,顺着作用域链向上查找
            console.log(b); // 2  是自由变量,顺着作用域链向上查找
            console.log(c); // 3  是自由变量,顺着作用域链向上查找
            console.log(d); //  4  是本作用域的变量
        }
        sum()
    }
    num()
}
fn()

匿名函数--自执行函数

(function () { 
    console.log(1); 
})()

注意:如果自执行函数上一行代码没有分号结尾 会报错

var a = 10
// ~:解决上一行代码没有分号结尾的问题
~(function () {
    console.log(1);
})()

为了解决自执行函数上一行可能忘了写分号导致报错,可以在自执行函数前面加一个 ~

自执行函数实现代码模块化

var utils = (function () {

    /* 
    @获取非行间样式
    @obj:元素
    @attr:属性
    */
    function getStyle(obj, attr) {
        if (window.getComputedStyle) {
            return window.getComputedStyle(obj)[attr]
        } else {
            return obj.currentStyle[attr]
        }
    }
    /* 
    计算和的函数
    @a:传入的范围值
    */
    function num(a) {
        var num = 0;
        for (var i = 0; i <= a; i  ) {
            num  = i
        }
        console.log(num);
    }
    // ............ 

    return {
        getStyle: getStyle,
        num: num,
    }

})()

// console.log(utils);  // utils = {  getStyle: getStyle, num: num,}
// 使用时直接传参数调用即可
utils.num(100)

解决下标获取不到的问题

window.onload = function () {
    var li = document.getElementsByTagName('li')

    for (var i = 0; i < li.length; i  ) {
        (function (i) { // 形参
            li[i].onclick = function () {
                console.log(i);
            }
        })(i) // 实参
    }
}

预解析--变量提升

浏览器解析代码的顺序是从上到下,从左到右,当遇到var关键字function关键字,会把变量以及等号还有函数体都提升到当前作用域的最顶端,浏览器会给变量赋值(这个值是undefined),然后保存到临时内存中,继续运行的时候,6
如果遇到 = 之类的赋值表达式或者计算表达式,就会给这个变量或者函数重新赋值

变量提升

console.log(a); // undefined  -- 变量提升赋值
var a = 10;
console.log(a); // 10  

函数提升

num(); // 函数提升
function num(){
    console.log('函数提升');
}

fn(); // 变量提升--会报错
var fn = function(){
    console.log('字变量函数');
}

如果函数名和变量名重名

/* 如果是关键字function声明的函数 函数的提升优先 */
console.log(num);

num(); // 函数提升
function num(){
    console.log('函数提升');
}
var num = 90


// 字变量方式的函数
console.log(fn); // 变量优先
var fn = 40
fn(); // 变量提升
var fn = function(){
    console.log('字变量函数');
}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkhbcj
系列文章
更多 icon
同类精品
更多 icon
继续加载