定义函数:以创建绝对值函数为例
function abs(x){
if(x>=0){
return x;
}
else{
return -x;
}
}
或
var abs=function(x){
if(x>=0){
return x;
}
else{
return -x;
}
}
其中,function(x)是匿名函数,结果赋值给abs,再通过abs调用函数,返回return后的值,若return后无值,则返回undefined。
调用函数:
调用函数中存在的参数问题:
1、引入的参数是否存在问题?若存在该如何解决?
2、若参数不存在,则如何规避?
可使用如下操作:
function abs(x){
if(typeof x!=='number'){
throw 'not a number';
//手动抛出异常--判断参数是否存在问题
}
if(x>=0){
return x;
}
else{
return -x;
}
}
参数获取:
argument:一个类数组(有数组的性质,可看作关键字),用来获取传递进来的所有参数。
var abs=function(x){
console.log("x=>"+x);//在多个参数的情况下,打印一个参数,只会打印出第一个。
for(var i=0;i<arguments.length;i++) {
console.log(arguments[i]);//,用数组,argument存储多个参数并打印
}
if(x>=0) {
return x;
} else {
return -x;
}
}
注意:数组argument包含所有参数,当想对多余的参数进行操作时,则需要排除已有的参数,用到rest。
rest:获取已定义参数外的所有参数。ES6引入的新特性
在rest引入前,若定义n个参数,要获取定义外参数,则需要(例)
var abs = function(x) {
if (arguments.length > 2) {
for (var i = 2; i < arguments.length; i++)
console.log(arguments[i]);
}
if(x>=0) {
return x;
} else {
return -x;
}
}
function f(a,b,…rest) {
//rest写到末尾,并且写为...rest
console.log("a=>"+a);
console.log("b=>"+b);
console.log(rest);//a,b为定义的参数,剩下的参数组成一个数组
}
在js中,var定义变量是有作用域的
1、例如,在某函数体内声明变量,则该函数体外不可用。
2、不同函数使用相同变量名,在各自函数体内使用互不影响。
3、内部函数可访问外部函数,反之不可。
function f1() {
var x=1;
function f2() {
//函数f2在f1内,f2可访问f1
var y=x+1; //变量y是可以被赋值的,x为1,y为2
}
var z=y+1;//在f1外部,自然也在f2外部,无法访问到函数里的y
//会显示Uncaught ReferenceError: y is not defined
}
提升变量作用域
例如:
function f() {
var x="x"+y;
console.log(x);
var y="y";
}
js执行引擎时,会自动提升y的声明,但不会为y赋值。上述代码本质上相当于在var x前vay y,在console.log后y=’‘y’’,所以x会显示undefined。因此,定义变量要放在函数头部,使其规范。
全局变量window
例如
var x="xxx";
alert(x);
等同于
var x="xxx";
window.alert(window.x);//默认所有的全局变量,都会自动绑定在window对象下
alert函数也是一个window下的全局变量
var x="xxx";
window.alert(x);
var old_alert=window.alert;
//old_alert(x);old_alert为变量,window.alert为弹窗功能
window.alert=function() {
};//创建一个空函数
window.alert(123);//123没有弹出,因为空函数使alert()失效了
window.alert=old_alert;//恢复:old_alert功能还在,重新赋值给window.alert
window.alert(456);//弹出456(可将123注释掉)
JS只有一个全局作用域,若变量没在函数作用范围内找到,则一步步向外查找,超出全局都没有则报错。因此,我们要使代码更规范,全局变量绑定在window对象上,不同的JS文件,如果使用相同的全局变量,则会冲突。所以我们可以尝试构建唯一全局变量。
例如:通过把代码全部放入定义的唯一空间名字中,降低全局命名冲突问题。
var win={
}
//定义全局变量
win.x= "xxx";
win.add=function(a,b) {
return a+b;
}
let局部作用域
在我前文中有提到let和var的区别:JavaScript-数据结构
要令let定义局部作用域的变量这一特性更明显,可看如下例子:
function a() {
for(var i=0;i<100;i++) {
console.log(i);//会一直打印
}
console.log(i+1);//i+1会被输出,为101,i出了作用域还可以使用
}
若var换成let,i+1会显示未定义。
const常量
同样也是ES6的新特性,在其出现前,定义常量就是全部大写,例如var PI=‘3.14’,并且这个值可以改变,但通常使用常量时,常量是不建议被改变的,所以使用const
const PI='3.14'
方法:函数放入对象。对象是由方法和属性组成。
例如:
var ming = {
//对象
属性,
属性,
age: function() {
//方法
var now = new Date().getFullYear();
return now-this.birth;
}
}
//调用属性
ming.属性
//调用方法,一定要带()
ming.age()
方法的提取:
var ming = {
age: getAge
}
function getAge() {
var now = new Date().getFullYear();
return now-this.birth;
}
ming.age();//20
getAge();//NaN,单独调用getAge是以window为对象,没有birth属性,由此可见this负责默认指向调用它的对象
}
因此可以使用apply控制this的指向。
getAge.apply(ming,[]);//this指向ming(对象),传入参数/数组,此处参数为空。
本文参考:Ping开源的博客