js笔记02-函数
定义方式
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
或者
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}; //但是要注意,这里有一个分号,因为这是一个赋值语句,将一个匿名函数赋给abs
arguments
函数定义后,有一个内部的关键字,只在内部起作用,并永远指向当前函数的调用者传入的所有参数
function foo(x) {
console.log('x = ' + x); // 10
for (var i=0; i<arguments.length; i++) {
console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
}
}
foo(10, 20, 30);
利用arguments
判断参数个数,完成中间的可选参数
// foo(a[, b], c)
// 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:
function foo(a, b, c) {
if (arguments.length === 2) {
// 实际拿到的参数是a和b,c为undefined
c = b; // 把b赋给c
b = null; // b变为默认值
}
// ...
}
rest
和arguments 类似,但是直接指向多余的变量,并以数组形式给出.
rest
参数只能写在最后,前面用...
标识
function sum(...rest) {
}
作用域
内部函数可以访问外部函数定义的变量,反过来则不行
变量提升
它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:
会提升变量的声明,但是不会提升变量的赋值
全局作用域
JavaScript默认有一个全局对象window
顶层函数也视为全局变量,并绑定到window
名字空间
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。
// 唯一的全局变量MYAPP:
var MYAPP = {};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函数:
MYAPP.foo = function () {
return 'foo';
};
局部作用域
var
的作用域是函数内部,所以:
function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; // 仍然可以引用变量i
}
块级使用let
代替var
常量
const
来定义常量 和let
一样,是块级作用域
解构赋值
传统
var array = ['hello', 'JavaScript', 'ES6'];
var x = array[0];
var y = array[1];
var z = array[2];
解构赋值
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
多个变量要用[...]
括起来
如果需要从一个对象中取出若干属性,也可以使用解构赋值,便于快速获取对象的指定属性:
var person = {
name: '小明',
age: 20,
gender: 'male',
passport: 'G-12345678',
school: 'No.4 middle school'
};
var {name, age, passport} = person;
可以
var x=1, y=2;
[x, y] = [y, x]
还可以获取当前页面的域名和路径
var {hostname:domain, pathname:path} = location;
方法
在一个对象中绑定函数,称为这个对象的方法。
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
方法内部,this
是一个特殊变量,它始终指向当前对象
this
是一个大坑
如果函数定义在全局位置,那么this
就指向window
如果还是按照上面那么写,然后这样调用
var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN
还是错的,this必须指向正确.
比较省心的办法是,在对象内部一开始就捕获this
用var that = this;
,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。
apply
也为了解决this
的问题,用apply
来指定,在对象外部定义的方法的this
的指向
它接收两个参数,第一个参数就是需要绑定的this
变量,第二个参数是Array
,表示函数本身的参数。
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
call()
也可以,不过就是 apply()
的第二个参数是Array
,call()
是将参数按顺序一个一个传入,可能更麻烦一点.
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
对普通函数调用,我们通常把this绑定为null。
装饰器
应用apply()
'use strict';
var count = 0;
var oldParseInt = parseInt; // 保存原函数
window.parseInt = function () {
count += 1;
return oldParseInt.apply(null, arguments); // 调用原函数
};