3、JavaScript函数
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
3.1 函数的定义和调用
定义方式一 建议使用
//定义绝对值函数
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
-
一旦执行到 return 时函数就执行完毕并将结果返回。
-
如果没有 return 语句函数执行完毕后也会返回结果只是结果为 undefined 。
定义方式二
//function (x) { ... } 是一个匿名函数它没有函数名。但这个匿名函数赋值给了变量abs通过变量abs就可以调用该函数。
var abs = function(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
方式一与方式二完全等价注意方式二需要在函数体末尾加一个分号表示赋值语句结束。
调用函数
abs(-5); // > 5
abs(5); // > 5
参数问题JavaScript 可以传任意个参数也可以不传参数
//假设不存在参数如何规避
var abs = function (x) {
if (typeof x!== 'number'){
//手动抛出异常
throw 'Not a number!';
}
if (x >= 0) {
return x;
} else {
return -x;
}
};
arguments
JavaScript免费赠送的关键字代表传递进来的所有参数是一个数组
var abs = function (x) {
console.log('x=>' + x);
for (var i=0; i<arguments.length; i++) {
console.log('arg ' + i + ' = ' + arguments[i]);
}
if (x >= 0) {
return x;
} else {
return -x;
}
};
问题arguments
包含所有的参数我们有时候想使用多余的参数来进行附加操作需要排除已有的的参数。
rest
以前
if (arguments.length>2){
for (var i=2; i<arguments.length; i++) {}
}
ES6 的新特性~ rest
获取除了已经定义的参数之外的所有参数
function aaa(a,b,...rest){
//rest参数只能写在最后面必须用...标识
console.log("a=>"+a);
console.log("b=>"+b);
console.log(rest);
}
aaa(1,1,1,1,1)
> a=>1
> b=>1
> (3) [1, 1, 1]
3.2 变量的作用域
在JavaScript中var定义的变量实际上是由作用域的
-
假设在函数体中声明则在函数体外不可以使用(非要实现的话需要使用
闭包
)'use strict'; function a(){ var x = 1; x = x + 1; } x = x + 2; //Uncaught ReferenceError: x is not defined
-
如果两个函数使用了相同的变量名只要在函数内部就不冲突
function a1(){ var x = 1; x = x + 1; } function a2(){ var x = 1; x = x + 1; }
-
内部函数可以访问外部函数的成员反之则不行
function a1(){ var x = 1; function a2(){ var y = x + 1; //2 } var z= y + 1; // Uncaught ReferenceError: z is not defined }
-
假设内部函数与外部函数的变量重名
function a1(){ var x = 1; function a2(){ var x = 'a'; console.log('内部'+x); } console.log('外部'+x); a2(); //内部a } a1(); //外部1
-
假设在JavaScript中函数查找变量从自身函数开始从“内”向“外”查找。如果内部函数定义了与 外部函数重名的变量则内部函数的变量将“屏蔽”外部函数的变量。
提升变量的作用域
function a(){
var x = 'x' + y;
console.log(x);
var y = 'y';
} //Uncaught ReferenceError: x is not defined
说明JavaScript执行引擎自动提升了y的声明但不会提升变量y的赋值这个是在JavaScript建立之初就存在的特性。
function a(){
//var x,y,z...;
//养成规范所有的变量定义都放在函数的头部不要乱放便于代码维护
var x = 'x' + y,
y = 'y',
z,a,b,c; //undefined
}
全局作用域
var x = 1;
function f(){
console.log(x);
}
console.log(x);
-
全局对象 window
-
var x = 'xxx'; alert(x); //直接调用alert() window.alert(x); //alert()本身也是一个window变量可以通过window对象来调用 alert(window.x); //默认所有的全局变量都会绑定在window对象下可以通过window对象来调用
-
玩一下发现JavaScript实际上只有一个全局作用域。任何变量函数也视为变量如果没有在当前函数作用域中找到就会继续往上查找最后如果在全局作用域中也没有找到则报 ReferenceError 错误。
'use strict'; window.alert('调用window.alert()'); // 把alert保存到另一个变量: var old_alert = window.alert; // 给alert赋一个新函数: window.alert = function () {} alert('无法用alert()显示了!'); // 恢复alert: window.alert = old_alert; alert('又可以用alert()了!');
-
规范
-
由于我们所有的全局变量会绑定到 window 上。如果不同的JavaScript文件使用了相同的全局变量就会发生冲突。
-
减少冲突把自己的代码全部放入自己定义的唯一名字空间中降低全局命名冲突的问题
//唯一全局变量 var JiangApp = {}; //定义全局变量 JiangApp.name = 'jiang'; JiangApp.add = function (a,b){ return a + b; }
-
局部作用域
let
建议使用
function a(){
for (i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1); // 101 i出了这个作用域还可以使用
//ES6 引入let关键字解决局部作用域冲突的问题
function a(){
for (let i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1); // Uncaught ReferenceError: z is not defined
常量
const
-
在 ES6 之前定义常量的方法只要用全部大写字母命名的变量就是常量建议不要修改这样的值
-
在 ES6 引入了常量关键字
const
const PI = 3.14; PI = 3; //Uncaught TypeError: Assignment to constant variable. PI; // 3.14
3.3 方法
定义方法
方法就是把函数放在对象的内部对象只有两个东西属性和方法
var me = {
name:'jiangjiang',
birth:2002,
age: function (){
var now = new Date().getFullYear();
return now-this.birth; //this默认指向调用它的那个对象
}
}
//调用属性
me.name; //'jiangjiang'
//调用方法一定要带()
me.age(); //21
拆开写
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
//此处this是无法改变指向的默认指向调用它的那个对象
}
var me = {
name: 'jiangjiang',
birth: 2002,
age: getAge
};
//调用
me.age(); // 21, 正常结果
getAge(); // NaN
apply 在Js中可以控制this的指向
getAge.apply(me,[]); //this指向了me这个对象参数为空
// 21, 正常结果