文章目录
**
函数
**
**
1.函数定义
**
1).第一种定义函数方法
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
上述abs()函数中:
1.function指出这是一个函数定义;
2.abs是函数的名称;
3.(x)括号内列出函数的参数,多个参数则用逗号(,)分隔;
2).第二种定义函数方法
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
上述方法中:
1.function (x) { … }是一个匿名函数,没有函数名;
2.匿名函数赋值给了变量abs,可通过变量abs调用该函数;
**
2.函数调用
**
调用函数时,按顺序传入参数即可
abs(10); // 返回10
abs(-9); // 返回9
JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题
abs(10, 'blablabla'); // 返回10
abs(-9, 'haha', 'hehe', null); // 返回9
传入的参数比定义的少也没有问题
abs(); // 返回NaN
要避免收到undefined,可以对参数进行检查
function abs(x) {
if (typeof x !== 'number') {
throw 'Not a number';
}
if (x >= 0) {
return x;
} else {
return -x;
}
}
**
3.arguments
**
只在函数内部起作用,永远指向函数内部调用者传入的所有参数
function a(x) {
console.log('x = '+ x);
for (var i = 0; i<arguments.length;i++){
console.log('arguments' + i + '=' + arguments[i]);
}
}
console.log(a(10,20,30,'小华','小明'));
**
4.rest参数
**
1).Rest 参数接受函数的多余参数,组成一个数组,放在形参的最后
function func(a, b, ...theArgs){
// ...
}
2).Rest 参数简化了使用 arguments 获取多余参数的方法
// arguments 方法
function func(a, b){
var args = Array.prototype.slice.call(arguments);
console.log(args)
}
func(1,2)
// Rest 方法
function func(a, b, ...args){
// ...
}
3).Rest参数和arguments对象的区别
1.rest参数只包括那些没有给出名称的参数,arguments包含所有参数;
2.arguments 对象不是真正的数组,而rest 参数是数组实例,可以直接应用sort, map, forEach, pop等方法;
3.arguments 对象拥有一些自己额外的功能;
**
5.变量作用和解构赋值
**
在JavaScript中,用var申明的变量实际上是有作用域的。
1).如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量
'use strict';
function foo() {
var x = 1;
x = x + 1;
}
x = x + 2; // ReferenceError! 无法在函数体外引用变量x
2).如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。
'use strict';
function foo() {
var x = 1;
x = x + 1;
}
function bar() {
var x = 'A';
x = x + 'B';
}
3).内部函数可以访问外部函数定义的变量,反过来则不行
'use strict';
function foo() {
var x = 1;
function bar() {
var y = x + 1; // bar可以访问foo的变量x!
}
var z = y + 1; // ReferenceError! foo不可以访问bar的变量y!
}
1.变量提升
会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部
'use strict';
function foo() {
var x = 'Hello, ' + y;
console.log(x);
var y = 'Bob';
}
foo();
在函数内部定义变量时,请严格遵守“在函数内部首先申明所有变量”这一规则.
2.全局作用域
不在任何函数内定义的变量就具有全局作用域。实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性
'use strict';
var course = 'Learn JavaScript';
alert(course); // 'Learn JavaScript'
alert(window.course); // 'Learn JavaScript'
由于函数定义有两种方式,以变量方式var foo = function () {}定义的函数实际上也是一个全局变量,因此,顶层函数的定义也被视为一个全局变量,并绑定到window对象
'use strict';
function foo() {
alert('foo');
}
foo(); // 直接调用foo()
window.foo(); // 通过window.foo()调用
3.名字空间
全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中
// 唯一的全局变量MYAPP:
var MYAPP = {};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函数:
MYAPP.foo = function () {
return 'foo';
};
4.局部作用域
JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中是无法定义具有局部作用域的变量的
'use strict';
function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; // 仍然可以引用变量i
}
5.常量
由于var和let申明的是变量,如果要申明一个常量,在ES6之前是不行的,我们通常用全部大写的变量来表示“这是一个常量,不要修改它的值"
var PI = 3.14;
ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域:
'use strict';
const PI = 3.14;
PI = 3; // 某些浏览器不报错,但是无效果!
PI; // 3.14
6.解构赋值
从ES6开始,JavaScript引入了解构赋值,可以同时对一组变量进行赋值。
var array = ['hello', 'JavaScript', 'ES6'];
var x = array[0];
var y = array[1];
var z = array[2];
在ES6中,可以使用解构赋值,直接对多个变量同时赋值
'use strict';
// 如果浏览器支持解构赋值就不会报错:
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
// x, y, z分别被赋值为数组对应元素:
console.log('x = ' + x + ', y = ' + y + ', z = ' + z);
**
6.函数方法
**
在一个对象中绑定函数,称为这个对象的方法。
绑定到对象上的函数称为方法,在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是a这个变量。所以,this.birth可以拿到a的birth属性。
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var a= {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25, 正常结果
getAge(); // NaN