一、Number数字类型:
- 正数/负数/零/小数
- Infinity 代指无穷大的值,-Infinity 代指负无穷大的值
- NaN(not a number)不是一个有效数字,但它却属于number类型
var num = 10-'A';//NaN
NaN == NaN;//false NaN和NaN本身都不相等(它和谁都不相等)
isNaN([value]) : 检测一个值[value]是否为"非有效数字",如果不是有效数字返回true,反之返回false.
-
在使用isNaN进行检测的时候,如果[value]是非数字类型的值,则浏览器默认会把 [value]转换为数字类型,然后再进行检测, "隐式转换":浏览器默认私下处理的.
-
在"隐式转换"中,浏览器是基于Number([value])实现数据类型转换的.
//需求:验证一个值是否为有效数字?
//这样处理不行,因为num==NaN永远不会成立
/* if(num==NaN){
alert('num不是有效数字!');
} */
//这样处理才是正确的
if(isNaN(num)){
alert('num不是有效数字!')
}
把其它数据类型转换为number数字类型
- Number([value]) : 而isNaN在检测的时候,使用的就是这种方式转换为数字类型的。 Number是JS内置的转换方法,可以把其他数据类型"强制"转换为数字类型。
- 字符串转换为数字:空字符串转换为0,如果字符串中出现任意一个非有效数字字符,结果都是转换为NaN。
- 布尔转换为数字:true->1,false->0.
- null->0,undefined->NaN.
- symbol值不能转换为数字(Uncaught TypeError:Cannot convert a Symbol value to a number)
- bigint 可以转换为数字.
- 引用数据类型(对象或者函数)转换为数字.
- 首先获取它的[Symbol.toPrimitive]属性值.
- 如果没有[Symbol.toPrimitive]这个属性,其次获取它的valueOf值(原始值)
- 如果还是没有valueOf值(原始值),最后把其转换为字符串toString(),然后再转换为数字 Number().
- 对象转换为数字:先把对象转化为字符串,再把字符串转化为数字.
- 普通对象
- 数组对象
- 其余对象格式基本都会变为数字NaN.
- 函数转化为数字,结果都是NaN.
console.log(Number('12'));//=>12
console.log(Number('12.5'));//=>12.5
console.log(Number('12px'));//=>NaN
console.log(Number('12.5.0'));//=>NaN
console.log(Number(true));//=>1
console.log(Number(false));//=>0
console.log(Number(null));//=>0
console.log(Number(undefined));//=>NaN
console.log(Number(symbol(13)));//=>报错
console.log(Number(function func(){}));//=>NaN
//1.先把obj转化为字符串"[object Object]"
//2.再把字符串转化为数字 Number("[object Object]")
let obj = {x:100}
console.log(Number(obj));//=>NaN
//1.先把arr转化为字符串"10"
//2.再把"10"转化为数字:10
let arr = ["10"]
console.log(Number(arr));=>10
//1.先把arr转化为字符串"10,20"
//2.再把"10"转化为数字:NaN
arr=["10","20"];
console.log(Number(arr));=>NaN
console.log(isNaN('AA'));//=>true
console.log(isNaN('12.5'));//=>false
console.log(isNaN('12.5px'));//=>true
console.log(isNaN([]));//=>false
console.log(isNaN([10]));//=>false
console.log(isNaN([10,20]));//=>true
console.log(isNaN({}));//=>true
console.log(isNaN(null));//=>false
console.log(isNaN(undefined));//=>true
console.log(isNaN(Symbol(1)));//报错
- parseInt([value])/parseFloat([value])
- 需要保证[value]是一个字符串,如果不是则首先"隐式"的把其转换为字符串[value].toString().
- 从字符串左侧第一个字符开始向右查找,把找到的有效数字字符,最后转换为数字(遇到一个非有效数字字符则停止查找,不论后面是否还有有效数字字符,都不再往后查找了)
- 如果一个有效数字字符都没有找到,结果还是NaN.
- parseFloat比parseInt多识别一个小数点.
<script>
console.log(Number('12px')); //=>NaN
console.log(parseInt('12px')); //=>12
console.log(parseInt('12px24')); //=>12
console.log(parseInt('width:12px')); //=>NaN
console.log(parseInt('12.5px')); //=>12
console.log(parseFloat('12.5px')); //=>12.5 parseFloat比parseInt多识别一个小数点
console.log(Number(true)); //=>1
console.log(parseInt(true)); //=>先把true转换为字符串"true" parseInt('true') =>NaN
console.log(parseInt(NaN)); //=>NaN
console.log(Number(null)); //=>0
console.log(parseInt(null)); //=> parseInt('null') =>NaN
console.log(isNaN(Number(parseInt("0.8")))); //=>parseInt("0.8")->0 Number(0)->0 isNaN(0)->false
console.log(Number('')); //=>0
console.log(parseInt('')); //=>NaN
</script>
结果为:
[number value].toFixed([N]):保留小数点后面N位.
<script>
//toFixed(N):保留小数点后面N位(最后的结果是一个字符串)
let n = 3.1415926;
console.log(n.toFixed(2)); //=>"3.14"
console.log(Number.MAX_SAFE_INTEGER); //=>9007199254740991 最大安全数(JS能够有效识别的最大整数)
console.log(9007199254740992 == 9007199254740993); //=>true 应该是false,但是超过了最大数值,JS无法精准计算.
//ES6中提供了一个新的数据类型 BigInt:管理超过安全数值的数字
console.log(BigInt(9007199254740992), BigInt(9007199254740993));
</script>
结果为:
二、字符串string数据类型
- 在JS中用单引号''/双引号""/反引号`` 包起来的都是字符串.
- 一个字符串是由零到多个字符组成的,每一个字符都有一个自己的位置"索引",有一个length存储字符串长度.
- 在字符串中每一个字符都有一个代表自己位置的"索引"(数字)
- 从0开始,逐级递增.
- 索引0:第一个字符,索引1:第二个字符.
- str[索引]获取指定索引位置的字符.
var str = "xiaoyunduo2021";
console.log(str.length); //=>14
console.log(str[0]); //=>'x'
console.log(str[str.length-1]); //=>'1'
-
字符串有很多自己能调用的方法: - chartAt - charCodeAt - substr - substring - slice - split - replace - indexOf/lastIndexOf - includes - trim - match - ...
//str.substr(n,m):从索引n开始截取"m"个字符,
//str.substring(n,m):从索引n开始找到"索引m"处(不含m),截取索引n和索引m(不含m)之间的字符
//m不写都是截取到字符串末尾,都不支持负索引,而slice是支持的(剩下的语法和substring一样)
var str = "xiaoyunduo";
console.log(str.substr(2,4)); // "aoyu"
console.log(str.substring(2,4)); //"ao"
- 把其它数据类型转换为字符串类型
- String([value])
- [value].toString()
- 字符串拼接
- 把对象转换为数字之前,先转化为字符串
- alert/confirm/prompt等.
- ...
- 特点:
- 基本上都是用双引号或单引号包起来即可.
- 普通对象转换为字符串不论对象中包括哪些信息,都是转化为 "[object Object]".
- 数组对象转换为字符串是 "第一项,第二项..."(逗号分隔数组中的每一项),[]转化为空字符串 ""
- 在JS中常用的数学运算
-
数学运算:+ - * / 加减乘除
-
%(膜)取余数
-
除了加法以外,其余的情况都是数学运算(如果遇到非数字类型,需要基于Number把其强制转换为数字类型,然后再进行运算);
-
加号在JS中既有数学运算,也有字符串拼接的意思(只要加号两边的任意一边出现字符串,则变为字符串拼接);
"+"加号的字符串拼接
- 加号的左右两边,有一边出现字符串,结果都是字符串拼接.
- 加号的左右两边,有一边出现对象(把对象转化为数字,进行数学运算)
-
首先获取对象的[Symbol.toPrimitive]/valueOf.
-
如果上述都没有获取原始值,则基于toString把对象转化为字符串.
-
此时出现问题"加号左右两边,有一边出现字符串了",这时就不再是数学运算,而是字符串拼接了.
-
加号出现一边,这样这一边即使是字符串/对象,也是数学运算.
-
如果是一个"{}"加内容,"{}"不参与运算,只是相对于一个代码块.
-
console.log(10+[10,20]);//=>[10,20][][Symbol.toPrimitive] undefined
//=>[10,20].valueOf() [10,20]不是原始值
//=> 此时10+"10,20" 这是字符串拼接了 => "1010,20"
console.log(10+new Number(10));//=>new Number(10)也是一个对象
//=> new Number(10)[Symbol.toPrimitive] undefined
//=> new Number(10).valueOf() 10
//=> 10+10 => 20
var s = "10";
console.log(+s); //=>10
console.log(+[10]); //=>10
console.log(s++); //=>10
console.log(s); //=>11
console.log(3 - "3px"); //=>NaN
console.log(3 + "3px"); //=>"33px" 字符串拼接
console.log(1 + "1"); //=>"11" 字符串拼接
console.log(1 + {}); //=>"1[object Object]" 在把{}转换为数字过程中,先把它转换为字符串"[object Object]",
此时右侧出现了字符串,则不再是数学运算,而是字符串拼接了.
console.log(1 + []); //=>'1' 在把[]转换为数字过程中,先把[]转化为空字符串,此时进行了字符串拼接,结果为'1'.
console.log([10] + true); //=>"10true" 在把[10]转换为数字的过程中,先把其转换为字符串"10",
此时操作变为字符串拼接(和数学运算没关系了).
console.log(true + [10]); //=>"true10"
console.log(1 + true); //=>2 */
console.log(4 / 2); //=>除 2
console.log(7 / 3); //=>除 2.3333333333333335
console.log(7 % 3); //=>取余 1
console.log(10 - null); //=>10
console.log(3 * undefined); //=>NaN
console.log(true - "12"); //=>1-12 =>-11
console.log(100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false);
/*
100 + true => 101
101 + 21.2 => 122.2
122.2 + null => 122.2
122.2 + undefined => NaN
NaN + "Tencent" => "NaNTencent" 字符串拼接(以后都是字符串拼接)
"NaNTencent" + [] => "NaNTencent"
"NaNTencent" + null => "NaNTencentnull"
"NaNTencentnull" + 9 => "NaNTencentnull9"
"NaNTencentnull9" + false => "NaNTencentnull9false"
*/
三、布尔数据类型及其它基本数据类型
1、布尔boolean数据类型: true/flase
-
如何把其它数据类型转换为布尔类型
- Boolean([value])
- !![value] 取反再取反,相当于没有取反,只是把它转换为布尔类型值
- 规则:只有 “0/NaN/null/undefined/空字符串” 结果是false,其余的都是true
![value] 把指定的值转换为布尔类型后取反
console.log(!!1); //=>true
console.log(!1); //=>false
console.log(!!-1); //=>true
console.log(!!0); //=>false
console.log(!!undefined); //=>false
console.log(!!Number('12px')); //=>Number('12px')->NaN false
console.log(!![]); //=>true
console.log(!!''); //=>false
console.log(!!{}); //=>true
/* 条件判断中,每一个条件最后一定是true/false */
if (1) {} //=>写一个值,也是要把这个值转换为布尔,然后校验程序的真假
if (3 + '3px') {} //=> 3 + '3px' =>'33px' 真true
if (3 - '3px') {} //=> 3 - '3px' => NaN 假false
if(10){} //首先会把10转换为布尔类型,然后验证真假,决定条件是否成立
2、symbol唯一值数据类型
console.log(Symbol() == Symbol()); //false 创建了两个唯一值
var n = Symbol();
console.log(n==n); //true 创建了一个唯一值
console.log(Symbol('AA') == Symbol('AA')); //false 加标识只是为了方便调试,依然是创建了两个唯一值
3、BigInt 大数数据类型
BigInt:字后面加个n即大数类型
- 真实场景:从服务器获取数据,服务器端存储数据的时候,如果用的计算大数存储的,返回到客户端的信息,很有可能超过最大安全数字,这样导致后续计算可能不准确。
Number.MAX_SAFE_INTEGER; //最大安全数 9007199254740991(16位)
Number.MIN_SAFE_INTEGER; //最小安全数 -9007199254740991
//超过最大安全数,再进行计算,结果是不准确的
console.log(9007199254740991+2); //9007199254740992
console.log(9007199254740992+3); //9007199254740996
BigInt("9007199254740992"); //=>9007199254740992n
四、对象数据类型
对象数据类型
-
普通对象 {} 「类数组、实例、原型对象...」
-
数组对象 []
-
正则对象 /^$/
-
日期对象
-
Set/Map
-
...
普通对象
1. 对象是由零到多组“键值对”(属性名:属性值)组成的
- 属性名(键)不是变量,它是对象的一个属性(特征)
- 属性名一般都是一个字符串(当然也可以是数字或者Symbol等基本类型的值)
- 属性名不能是对象或函数,对象或者函数作为属性名,浏览器会把其转换为字符串
var x = {
xx: 'xxx'
};
var y = {
//name叫做属性名,此处本身也是一个字符串 "name"
// "云朵"是当前name属性的属性值
name: "云朵",
age: 11,
0: 100,
// 对于Symbol类型的属性名,需要基于[]包裹起来,保证语法正确性
[Symbol('AA')]: 200,
// 属性名不是这个对象,而是变为最后的字符串 ({xx:'xxx'}).toString() => "[object Object]"
[{xx:'xxx'}]:300,
// x->"x" 这个x和上面的x没有关系,它是一个字符串x
x: 300
};
console.log(y);
let n = {
x: 100
};
let m = [100, 200];
let obj = {};
obj[n] = "云朵"; //=>obj[{x:100}] 但是对象不能作为属性名,需要把其转换为字符串 =>{"[object Object]":"云朵" }
obj[m] = "云朵"; //=>obj[[100,200]] =>{ "100,200":"云朵" }
console.log(obj);
2. 获取一个对象中某个属性名对应的属性值,也称“对象的成员访问”.
- 对象.属性名 :这种方式不适用于“数字或Symbol的类型”的属性名,这样的情况只能基于 对象[属性名] 来访问.
- 对象[属性名] :这种方式必须指定好属性的类型,若是字符串,必须加"" ,而 “obj[name] 和 obj["name"] 不是一个情况”.
let obj = {
sex: 0
};
// 1.获取指定属性名的属性值.
console.log(obj.sex); //=>0
console.log(obj['sex']); //=>0
//2.如果指定的属性不存在,获取到的属性值是undefined(不会报错)
console.log(obj['age']); //=>undefined
// 3.获取当前对象中所有的属性名:返回结果是包含所有属性名的数组.
console.log(Object.keys(obj)); // =>["sex"]
var obj = {
name: '云朵',
0: 100
};
console.log(obj.name); //'云朵'
console.log(obj["name"]); //'云朵'
console.log(obj[0]); //100
console.log(obj.0); //Uncaught SyntaxError: missing ) after argument list
console.log(obj.age); //访问对象的某个成员,如果当前成员没有在对象中,不会报错,访问到的结果是undefined而已
console.log(age); //如果是访问一个不存在变量,则会报错 Uncaught ReferenceError: age is not defined
obj['x']和obj[x]的区别
-
'x' 字符串类型的值.
-
x 它不是值,它是一个变量,代表变量x存储的值10.
-
obj[值] 直接是对象的成员访问.
-
obj[变量] 首先获取变量x值,然后把变量x存储的值作为属性名,再进行对象的成员访问.
ar x = 10;
var obj = {
x: "云朵",
10: 100
};
console.log(obj.x); //访问当前对象属性名是"x"对应的属性值 ->"云朵"
console.log(obj['x']); //和上面操作是一个意思,也是访问"x"的属性值 ->"云朵"
console.log(obj[x]); //首先获取x变量存储的值,把存储的值10作为属性名,进行对象的成员访问 => obj[10] ->100
let n = 100;
let obj = {
1: 100
};
console.log(obj[1]);
console.log(obj.1); //=>Uncaught SyntaxError: missing ) after argument list 基于点的方式操作有自己的局限性,属性名不能是数字的,不能 对象.数字属性,此时只能用 对象[数字属性]
console.log(obj[1]);
console.log(obj['1']); //=>其它非字符串格式作为属性名和字符串格式没啥区别
obj.n = 200; //=> {n:200} n是属性名(数据格式是字符串)
obj['n'] = 200; //=> {n:200}
obj[n] = 200; //=> {100:200} => obj[100]=200 n本身是一个变量(n和'n'的区别:前者是一个变量,后者是一个字符串的值),它代表的是所存储的值100(是一个数字格式)
obj[m] = 200; //=>Uncaught ReferenceError: m is not defined m这个变量没有被定义
obj[true] = 300; //=>{true:300}
obj[undefined] = 400; //=>{undefined:400}
3. 管理一个对象的成员
-
直接编写在大括号{}中的,(而对于Symbol或者对象类型的属性名,以及需要把一个变量存储的值作为属性名,都需要基于中括号[]包裹起来,保证语法的正确性)
-
基于JS动态管理成员(新增/修改/删除)
-
对象的成员是不允许重复的(0和'0'是按照相同的成员处理的),在动态管控的时候,之前有这个成员则是修改成员的属性值,没有这个成员才是给对象新增一个成员.
var symb = Symbol('xx');
var obj = {
name: '云朵',
0: 10,
// symb: 'xxx', //这样处理,属性名就是"symb",而不是这个变量存储的值
[symb]: 'xxx' //这样处理,属性名是Symbol(xx),等同于把变量存储的值作为属性名
};
console.log(obj[symb]); //=>'xxx'
var symb = Symbol('xx');
var obj = {
name: '云朵',
0: 10
};
obj.age = 11; //给obj增加age这个属性
obj["age"] = 11; //给obj增加age这个属性
obj["symb"] = 'xxx'; //相当于给obj增加symb:'xxx'这个属性
obj[symb] = 'xxx'; // -> obj[Symbol(xx)]='xxx' 相当于给obj增加Symbol('xx'):'xxx'这个属性
obj['name'] = "云朵"; //相当于修改了name这个属性
console.log(obj[0]); //=>10
console.log(obj["0"]); //=>10
// 假删除:利用访问对象不存在的成员,返回undefined的特征,我们把某个成员的值修改为undefined,
这样以后再获取这个成员,结果也是undefined,我们则可以认为当前成员是不存在(本质还是存在的)
obj.name = undefined;
// 真删除:彻底从对象中移除这个成员
delete obj["name"];
console.log(obj);
特殊对象
特殊对象:数组或者类数组对象(集合).
-
属性名(成员/键)是数字,而且数字从零开始,逐级递增,
- 有顺序和规律的数字属性名被称为“索引”:记录每一项的位置信息的.
- 第一项索引是0,第二项索引是1...最后一项索引是length-1.
-
有一个length成员,存储集合的长度.
“数组/类数组[索引]” 进行成员访问以及相关的操作.
// 数组 =>它是Array类的实例,用[]包起来.
var arr = [10, 20, 30];
console.log(arr[0]); //获取第一项的值
console.log(arr[arr.length - 1]); //获取最后一项的值
console.log(arr);
// 类数组(类似于数组,但不是数组) =>不是Array的实例,虽然结构类似,但是不能直接使用数组的办法
var obj = {
0: 10,
1: 20,
2: 30,
length: 3
};
console.log(obj);
// HTMLCollection元素集合:类数组
console.log(document.getElementsByTagName('*'));
// NodeList节点集合:类数组
console.log(document.querySelectorAll('*'));
五、函数function数据类型
函数 : 就是一个方法,可以实现某个功能.
为什么会有对象呢?
- 我们把描述当前事物的属性或者方法(特点)存放在一起,防止变量的覆盖或者冲突
var person1={
name:'xxx',
age:25
};
为什么会有函数呢?
-
函数其实就是一个方法/一个功能体
-
封装:把实现当前功能的代码封装到函数中,后期想要实现这个功能直接调用函数执行,无需重新编写代码,这样提高了开发的效率,减少了页面中的冗余代码 “低耦合,高内聚”
-
闭包:私有化
-
...
var n = 10,
m = 20;
var total = n + m;
var average = (total / 2).toFixed(2);
console.log(average);
var n = 17,
m = 28;
var total = n + m;
var average = (total / 2).toFixed(2);
console.log(average);
var n = 189,
m = 231;
var total = n + m;
var average = (total / 2).toFixed(2);
console.log(average);
创建函数 function sum(x, y){...}
-
sum函数名(等同于变量,也是声明一个sum变量,只不过存储的值是一个函数)
-
x或y :形参(变量),存储传递实参信息的,它是函数提供的一个入口(原因:封装这个功能,很多信息信息此时不清楚,执行时候用户传递给我才清楚)
-
{...}函数体:编写具体功能代码的区域
function sum(x, y) {
//console.log(sum); //-> ƒ sum(x, y) {} sum变量(函数名)代表的是函数本身
var total = x + y,
average = total / 2;
average = average.toFixed(2);
console.log(average);
}
执行函数 函数(实参1,实参2,...)
-
实参(具体的值):就是给函数的形参变量传递的具体值.
sum(17, 28);
sum(189, 231);
sum(); //x=undefined y=undefined
sum(10); //x=10 y=undefined => NaN 创建函数定义了形参,但是执行时候没有传递实参值,则默认形参变量的值是undefined
sum(10, 20); //x=10 y=20 =>15.00
sum(10, 20, 30); //x=10 y=20 =>15.00
项目中一般会对形参进行默认值处理
- if条件判断
function sum(x, y) {
if (x === undefined) //若x没有传值,则x = 0.
{
x = 0;
}
if (y === undefined)
//if (typeof y === "undefined")
{
y = 0;
}
var total = x + y,
average = total / 2;
average = average.toFixed(2);
console.log(average);
}
sum(); // =>0
sum(10); // x=10 y=0 => 5.00
sum(10, 20); // x=10 y=20 =>15.00
sum(10, 20, 30); // =>15.00
- 逻辑或|| 和 逻辑与&&
-
A||B 首先看A是真还是假,如果A是真返回A的值,如果A是假返回B的值.
-
A&&B 首先看A是真还是假,如果A是真返回B的值,如果A是假返回A的值.
-
两者同时出现,&&优先级高于||. 只有“0/NaN/空字符串/null/undefined”是假,其余都是真.
-
function sum(x, y) {
// 对于 x = x || 0; 这个办法,x或y的值不仅仅是undefined会变为0,当x或y的值是 0/NaN/空字符串/null 的时候也都会变为0,这种方法相对不严谨,但是可以这样处理.
x = x || 0; //当x是undefined即x为假时,返回0.
y = y || 0;
var total = x + y,
average = total / 2;
average = average.toFixed(2);
console.log(average);
}
sum(); // =>0
sum(10); // x=10 y=0 => 5.00
sum(10, 20); // x=10 y=20 =>15.00
sum(10, 20, 30); // =>15.00
- ES6中的形参赋值默认值
- 设定形参不传递值,这时形参为等号后面的默认值,
- 但是一旦传递值了(undefined除外,当传的值是undefined时,形参为0),不论传递什么都不会为默认值.
function sum(x = 0, y = 0) {
var total = x + y,
average = total / 2;
average = average.toFixed(2);
// 在函数体中一定可以拿到处理完成的结果的
console.log(average); //"15.00"
}
sum(10, 20);
console.log(average); // Uncaught ReferenceError: average is not defined (在函数体外,是不能直接访问函数体中的内容的,函数内部的东西,是不允许我们直接拿函数内部东西的(内部的东西是私有的变量))
函数的出口:返回值机制
return
-
return后面是啥,返回值就是啥.
-
不写return或return后面啥都没有,默认返回值都是undefined.
-
函数体中只要遇到return,函数体中,return下面的代码都不会再执行的.
-
return的一定是一个值,return average也不是返回变量,而是把变量存储的结果返回 -> return '15.00'.
function sum(x = 0, y = 0) {
var total = x + y,
average = total / 2;
average = average.toFixed(2);
return average; //-> return '15.00'
// 函数体中只要遇到return,函数体中,return下面的代码都不会再执行的
console.log('OK');
}
var result = sum(10, 20);// sum(10, 20)返回的值是15.00
console.log(result);// => 15.00
正常创建函数:声明一个变量叫做fn(函数名),只不过存储的值是一个函数.
function fn() {}
匿名函数(没有函数名字)
-
函数表达式:把创建的函数当作值,赋值给变量或者其他内容.
-
自执行函数:创建函数和执行函数一起完成了.
“函数表达式”创建函数:和上面方式的效果是一样的(在变量提升中有一些区别)
var fn = function () {
// 这个里面也相当于函数表达式:创建一个匿名函数,把其作为值返回.
return function () {}
};
var f = fn();
//事件绑定:把函数当作值赋值给body的点击事件,当点击body的时候触发函数执行
document.body.onclick = function () {};
自执行函数:第一个小括号中存放的是创建的函数,第二个小括号是把函数执行
(function (x) {
// ...
})(100); //实参100传给了形参x.
//除了用小括号把函数包裹起来可以解决语法错误(因为创建的函数没有名字)的问题,在前面加 ~、+、-、! 也都可以让语法正确
~ function (x) {
// ...
}(100);
需求:执行函数的时候传递实参值,但是传递多少个实参“不确定”,我们想接受函数传递的实参信息.
- 设定形参变量:但是需要知道传递实参的数量和顺序.
- 函数内置实参集合 arguments(兼容所有浏览器):不论是否传递以及传递多少实参(也不管是否设定形参),集合中包含了所有传递的是实参信息.
- 不传递就是一个空集合.
- 这个集合是一个“类数组”.
- ES6中的“...”剩余运算符(ES6中的,不兼容一般浏览器):函数形参中的剩余运算符,可以获取到,除前面设定形参变量接收到的实参外,剩下的实参都放到这个集合中.
-
如果一个形参变量都没有定义,则所有传递的实参信息都存到这个集合中.
-
这个集合是一个“数组”集合,params变量存储参数集合.
-
function fn(...params) {
console.log(params);
//console.log(arguments);
//console.log(params,arguments);
}
fn();
fn(10);
fn(10, 20);
fn(10, 20, 30);
ES6中“创建函数”的新方式:“箭头函数”「所有箭头函数都是函数表达式创建方式」
-
创建函数的语法不一样.
-
执行函数是一致的. fn()
var xxx = ([形参])=>{
[函数体]
}
- 箭头函数
-
如果只有一个形参,可以不加小括号
-
如果函数体中只有一句话,而且是return xxx的,则可以省略函数体的大括号和return...
-
箭头函数中没有arguments(想获得函数传递的所有实参信息但传递多少个实参“不确定”时,只能使用剩余运算符"..."了)
-
function fn(x) {
return x * 10;
}
//改为箭头函数
var fn = (x) => {
return x * 10;
};
// 只有一个形参,可以不加小括号
// 如果函数体中只有一句话,而且是return xxx的,则可以省略函数体的大括号和return...
// 即为
var fn = x => x * 10;
function fn(x) {
return function (y) {
return x + y;
};
}
//改写为箭头函数
var fn = x => y => x + y