3. 函数
3.1 定义函数
定义方式一
function abs(x){
if(x>=0){
return x;
}else{
return -x;
}
}
abs(10) //10
abs(-10) //10
- 执行到return代表函数结束
- 没有执行return,函数执行完也会返回结果,结果为undefined
定义方式二
var abs = function(x){
if(x>=0){
return x;
}else{
return -x;
}
}
**function(x){…} **这是一个匿名函数。但是可以吧结果赋值给abs,通过abs调用函数
方式一和方式二等价
**参数问题:**JavaScript 可以传任意个参数,也可以不穿参数
参数进来是否存在的问题?
假设不存在参数,如何规避?
var abs = function (x) {
//手动抛出异常
if (typeof x !== 'number') {
throw 'Not a number';
}
if (x >= 0) {
return x;
} else {
return -x;
}
}
arguments
arguments代表传递进来的所有参数,是一个数组
var abs = function (x) {
console.log("x=>"+x);
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
if (x >= 0) {
return x;
} else {
return -x;
}
}
rest
以前
if (arguments.length>2){
for(var i=2; i<arguments.length; i++){
//......
}
ES6新特性:获取除了已经定义的参数之外的所有参数
function aaa(a, b, ...rest) {
console.log("a =>" + a);
console.log("a =>" + b);
console.log(rest);
}
rest参数只能写在最后面,必须用…标识
3.2 变量的作用域
在JavaScript中,var定义的变量实际是有作用域的
- 假设在函数体中声明,则在函数体外不可以使用
function aaa(){
var x = 1;
x = x+1;
}
x = x+2;
- 如果两个函数使用了相同的变量名,只要在函数内部,就不冲突
function aaa(){
var x = 1;
x = x+1;
}
function bbb(){
var x = 'A';
x = x+1;
}
- 内部函数可以访问外部函数的成员,反之不行
function aaa(){
var x = 1;
function bbb(){
var y = x+1;
}
var z = y+1;
}
- 假设内部函数变量和外部函数变量重名,
function aaa(){
var x = 1;
function bbb(){
var x = 'A';
console.log('inner' + x); //outer
}
console.log('outer' + x); //inner
bbb()
}
aaa()
//outer1
//innerA
假设在JavaScript中函数查找变量从自身函数开始,由内向外查找。假设外部存在这个同名的外部变量,则内部函数会屏蔽外部函数的变量
全局函数
//全局变量
x = 1;
function aaa(){
console.log(x);
}
aaa();
console.log(x);
全局对象window
var x = 'xxx';
alert(x);
alert(window.x) //默认所有的全局变量,都会自动绑定在window对象下
**alert()**这个函数本身也是一个window
变量
- JavaScript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错
ReferenceError
规范
由于我们所有的全局变量都会绑定到window上,如果不同的js文件,使用了相同的全局变量,冲突->如何减少冲突?
//唯一全局变量
var App = {};
//定义全局变量
App.name = 'App';
App.add = function (a, b) {
return a + b;
}
把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题
jQuery = $
局部作用域let
function aaa(){
for (var i=0;i<100;++){
console.log(i);
}
conso1e.1og(i+1);//i出了这个作用域还可以使用
}
ES6let关键字,解决局部作用域冲突的问题
function aaa(){
for (let i=0;i<100;++){
console.log(i);
}
conso1e.1og(i+1);// Uncaught ReferenceError: i is not define
}
- 建议局部作用域变量都使用let
常量const
在ES6之前,定义常量:只有用全部大写命名的变量就是常量(约定俗成);建议不要修改这样的值
var PI = '3.14';
console.log(PI);
PI = '123'; // 可以被改变
console.log(PI);
在ES6引入常量关键字const
const PI = '3.14'; // 只读变量
console.log(PI);
PI = '123'; // 无法修改
3.3 方法
定义方法:就是把函数放在对象里面,对象只有两个东西:属性和方法
var jack = {
name: 'Jack',
birth: 2020,
//方法
age: function () {
var now = new Date().getFullYear();
return now - this.birth;
}
}
//jack.age()
//2
this代表什么?
function getAge(){
var now = new Date().getFullYear();
return now - this.birth;
}
var jack = {
name: 'Jack',
birth: 2020,
//方法
age: getAge
}
//jack.age() ok
//getAge() NaN this指向window
this是无法指向的,是默认指向调用它的那个对象;
apply
在js中可以控制this的指向!!!
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
}
var jack = {
name: 'Jack',
birth: 2020,
//方法
age: getAge
};
getAge.apply(jack,[]);//this指向了jack对象,参数为空