[JavaScript语法学习]全面介绍函数

函数

ES6语法支持rest参数

rest参数只能定义在参数最后面,用...标识。如果传入的参数连正常定义的参数都没有填满,则rest参数会接收一个空数组。

变量作用域

用var声明的变量实际上都是有作用域的,内部函数可以访问外部函数定义的变量,查找变量时都是从自身函数定义开始,从内向外查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将屏蔽外部函数的变量。

变量提升

JS函数会先扫描整个函数体的语句把所有声明的变量提升到函数顶部。因此建议在函数内部定义变量时请严格遵守“函数内部首先声明所有变量”规则。

全局作用域

不在任何函数内定义的变量都具有全局作用域,默认全局对象window

namespace命名空间

将所有的变量和函数全部绑定在一个全局变量中

局部作用域

ES5没有块级作用域,因此在ES6中,引入了let关键字。用let代替var可以声明一个块级作用域变量

常量

在ES6中引入了const关键字来定义常量,const和let都具有块级作用域

this

在一个独立的函数作用域中,如果this没有指定某个对象。那么在严格模式下this指向undefined,在非严格模式下this指向window

如果更改this的指向呢?

1. apply方法可以指定函数的this指向,接收两个参数,第一个是this需要绑定的变量,第二个表示函数本身的参数数组

2. call方法会把参数按照顺序打包成Array进行传入

普通函数的调用通常是把this绑定为null

var count = 0;
var oldParseInt = parseInt;
window.parseInt = function(){
    count+=1;
    return oldParseInt.apply(null, arguments);
};

闭包

在函数内部定义的函数能够访问外部函数的局部变量的特性被称为闭包

经典大坑:返回函数不要引用任何循环变量或者后续会发生变化的变量

function count(){
    var arr=[];
    for(var i=1; i<=3; i++){
        arr.push(function(){
            return i*i;
        });
    }
    return arr;
}
var results = count();
var f1= results[0];
var f2= results[1];
var f3= results[2];
f1();
f2();
f3();
// 这三个函数的返回值都是16

ES6对函数的扩展

1. 函数参数的默认值

ES6可以给函数的参数指定默认值,可以避免在ES5中使用 || 的语法实现默认值

但是这样有一个缺陷,或语句逻辑表达式的第一个参数的布尔值如果为false那么也会使用默认值。 比如传入一个空字符串,转换为布尔值就是false

所以一般都要先判断该变量是否有值

// ES5 语法
function log(x, y){
    if(typeof y == ‘undefined‘){
        y = ‘world‘;
    }
}

function log(x, y){
    if(arguments.length == 1){
        y = ‘world‘;
    }
}

在ES6中,直接在参数定义后面使用等号进行默认值赋值

function log(x, y = "world"){
    console.log(x, y);
}

log("hello");  // hello world

log("hello", "es6");  // hello es6

log("hello", "");  // hello

参数变量是默认声明的,所以不能在函数体内再次使用 let 或者 const 声明。

小坑:

如果函数参数是一个对象,但是并没有给整个对象赋予默认值时。那么调用函数时如果不传入参数,则会报错。

最后时刻警惕下列情况

function m1({x = 0 , y = 0} = {}){
    return [x, y];
}

function m2({x, y} = {x: 0, y: 0}){
    return [x, y];
}

参数默认值的位置必须是最后一个函数参数,如果不是最后一个参数,则有默认值的参数需要显示传入undefined才能跳过该参数,而null是无法跳过的。这一点可以参考对象的解构赋值

2. 函数的length属性

函数的length属性 = 函数的参数个数 - 指定了默认值的参数个数

rest参数也不会计入length属性

3. 作用域

如果参数默认值是一个变量,则该变量所处的作用域与其他变量的作用域规则是一样的。先是当前函数作用域,再是全局作用域。

如果函数调用时默认值变量尚未在函数内部生成时,那么该变量会指向全局作用域。

如果函数调用时默认值是一个函数,那么函数作用域是声明时所在的作用域,也就是全局作用域。

4. rest参数

ES6引入了Rest参数,Rest参数必须是最后一个参数,也就是得放在普通参数和默认值参数之后。

Rest参数可以代替arguments变量

const sortNumbers = () => [].prototype.slice.call(arguments).sort();

const sortNumbers = (...numbers) => numbers.sort(); 

Rest参数变量代表一个数组,所以数组方法都可以用在这个变量上。

function push(array, ...items){
    items.forEach( (item) => {
        array.push(item);
    });
}

var arr = [];
push(arr, 1, 2, 3, 4);

5. spread扩展运算符

可以将一个数组转换为用逗号分隔的参数序列,用途:

1. 替代数组的apply方法

2. 合并数组

3. 与解析赋值结合

4. 函数返回值解析

5. 字符串解析

6. 类数组对象的解析

6. 函数的name属性

ES6才将name属性写进标准中,但是很多浏览器都已经实现了这个功能

另外ES6规定了匿名函数也是有name属性的,也会返回实际的函数名。而在大部分浏览器中则依然返回空字符串

Function构造函数返回的函数实例,name属性 = ‘anonymous‘

函数通过bind()方法进行this绑定后,返回的函数的name属性会在原先的name属性值上添加"bound "前缀

7. 箭头函数 (重点中的重点)

1. 如果函数不需要参数或者需要多个参数,需要使用()将参数部分包围。 仅仅对于只有一个参数的函数可以省略掉()

2. 如果函数体多于一条语句,需要使用{}将函数体包围。并使用return 语句返回。 对于一条语句可以省略{}

3. 如果函数返回的是对象,那么就需要在{}外面套上()

4. 函数体内的this对象已经改变了,表示的是函数定义时所在的对象。而不是原来的使用时所在的对象。

5. 箭头函数不能作为构造函数进行使用

6. 箭头函数中不能使用arguments对象

7. 箭头函数中不能使用yield语句

8. 箭头函数实质上是没有this的,同时arguments, super, new.target也都不存在

时间: 2024-10-13 14:36:06

[JavaScript语法学习]全面介绍函数的相关文章

[JavaScript语法学习]全面介绍Array

Array Array可以包含任意数据类型,并通过索引来访问每个元素.直接给Array的length属性赋予一个新的值会导致Array大小的变化,其中未赋值的数据就是undefined. 因此不建议直接修改Array的大小,同时确保索引访问时不会出现索引越界. 属性 length prototype 方法 Array.isArray() Array.prototype.pop()   删掉最后一个元素 Array.prototype.push()  末尾添加若干元素 Array.prototyp

[JavaScript语法学习]全面介绍String

String是一串Unicode字符序列.String全局对象是用来构造字符串对象或者字符序列的构造函数 语法 1. 字符串的字面量语法,在ES6标准中,称为模板字面量.具体可以参考TypeScript 2. String构造函数   String(thing) /  new String(thing) 转义字符 \0  \'  \"  \\  \n  \r  \t  \v  \b  \f  \uXXXX 长字符串 两种方法: 1. 使用+运算符将多个字符串连接 2. 每行末尾使用反斜杠 \ 以

[JavaScript语法学习]全面介绍对象

对象的属性判断方法 1. in 2. hasOwnProperty() JS中的对象的属性(键名)必须是字符串,为了弥补和其他语言的差距(键名可以是任意类型) 在最新ES6标准中引入了Map和Set 在ES6标准中引入了iterable类型,Array  Map Set都属于iterable类型,可以使用for...of循环来遍历 for...of循环只会循环集合本身元素 ES5.1标准 forEach forEach(element, index, array) ES6对Object的扩展 1

javascript语法基础-变量与函数

三 javascript语法基础-变量与函数 (一)变量的声明与运用 JavaScript中的变量与Java.C等强类型语言有很大区别,虽然在JavaScript中具有字符串.数字等数据类型. 变量申明语句的结构是var保留字加标识符,var和标识符之间用空格隔开. 赋值语句的结构是在变量和需要赋的值之间加上一个等号,例如a=1的含义是将变量a的值指定为1. 变量在定义的时候也可以同时赋值,如var a=1. PS:在变量使用前事先进行声明是个良好的编程习惯,这对将来学习Java等其他语言有帮助

JavaScript语法学习笔记

1.关于执行JavaScript代码的方法: 第一种方法是将JavaScript代码放到文档<head>标签中的<script>标签之间: <head>     <meta charset="utf-8"> <title>index</title> <script> JavaScript goes here.... </script> </head> 第二种方法是讲JavaScr

JavaScript入门学习之二——函数

在前一章中讲了JavaScript的入门语法,在这一章要看看函数的使用. 函数的定义 JavaScript中的函数和Python中的非常类似,只不过定义的方式有些不同,下面看看是怎么定义的 //定义普通函数 function f1(){ console.log('hello world!') } //定义带参数的函数 function f2(a,b){ console.log(a) console.log(b) } //定义带返回值的函数 function f3(a,b){ return a+b

Swift高级语法学习总结(转)

Swift高级语法学习总结 1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参数需要指明类型,而如果没有返回值可以不写->(),返回值只需要写返回类型,如果写了返回名称,可以在函数调用后的值用点语法访问 1.3 在参数名称前可以加上外部参数名,调用的时候就可以带上它了,如果外部参数名和内部参数名相同则可以直接在内部参数名前加#即可 1.4 如果跟参数设置一个默认值,则swift会

javascript学习3-自定义函数

javascript自定义函数,很简单的小例子. 实现效果:输入两个数和运算符号,根据不同运算符对数据进行计算,返回值 代码: 1 <html> 2 <head> 3 <script type="text/javascript"> 4 var num1=window.prompt('请输入第一个num'); 5 var num2=window.prompt('请输入第二个num'); 6 var operator=window.prompt('请输入

【JavaScript】02.基础语法学习

[JavaScript]02.基础语法学习 引言: 老农认为(老农是我对自己的昵称),学习任何一门计算机程序语言都要先从它的语法知识开始.计算机程序语言由一堆预定义的字符和书写这些字符的规则组成.这些预定义的字符在语言里面叫做关键字或者保留字,书写这些字符的规则叫做语法. 计算机语言(Computer Lnguage),是指用于人与计算机之间通讯的语言.语言分为自然语言与人工语言两大类.自然语言是人类在自身发展的过程中形成的语言,是人与人之间传递信息的媒介.人工语言指的是人们为了某种目的而自行设