函数
1) 作用 — 函数也是对象,是一个援用数据类型
1. 利用函数能够封装一些具备非凡性能的代码,之后调用即可实现相应的成果
arr.sort(); // 排序
arr.reverse(); // 反转
jQuery();
ajax(); // http 申请
2. 利用函数封装对象【api 实质 / 构造函数】高级面向对象
2) 函数创立形式 – 函数创立结束后个别不会主动执行,须要调用
-
函数申明
function 函数名(形参列表){// 函数体} function sayMsg(name,age,gender){console.log('name:',name); console.log('age:',age); console.log('gender:',gender); } sayMsg('zhangsan',13,'male'); 实参的程序与形参的程序是一一对应的 形参能够是对象,拜访时 obj. 属性
-
函数表达式 — 匿名函数赋值给变量
var 函数名 = function(形参列表){// 函数体};var fun = function(name,age){console.log(name); console.log(age); } fun.call(this,'tom',20,'male'); fun.apply(this,['larry',18,'female']);
3) 调用形式
调用时解析器不会查看实参类型,数量
多余的实参不会被赋值,实参有余,没有对应实参的形参是 undefined
函数体 return 后的语句不会执行
return 后无值,无 return --- 返回 undefined
函数名(实参列表);
函数名.call(this, 实参列表);
函数名.apply(this, 实参数组);
sayMsg('zhangsan',13,'male');
fun.call(this,'tom',20,'male');
fun.apply(this,['larry',18,'female']);
4) 晋升
代码从它们在代码中呈现的地位被挪动到以后作用域最上方进行执行【解析器操作的】,这个过程叫做晋升
-
变量的晋升 -> 用 var 申明的变量会在所有代码执行前被申明(然而不会被赋值)
1>a = 1; var a; console.log(a); ==> 等价于 var a; a = 1; console.log(a); // 1
2>
console.log(a); var a = 1; ==> 等价于 var a; console.log(a); // undefined -- a 未被赋值 a = 1;
-
函数申明的晋升 -> 用函数申明形式创立的函数(function a(){}), 会在所有代码执行前被创立
1> test(); function test(){console.log(1); } ==> 等价于 function test(){console.log(1); } test(); // 1 2> fun(); var fun = function(){ // 函数表达式创立 console.log(1); } ==> 等价于 var fun; fun(); // fun is not a function fun = function(){console.log(1); }
-
函数申明与函数表达式的晋升 -> 函数申明的晋升优先于函数表达式
var fun = function(){console.log(2); } fun(); function fun(){console.log(1); } ==> 等价于 function fun(){console.log(1); } var fun = function(){console.log(2); } fun();
5) 援用数据类型的比拟
同一个指针不能够同时指向多个堆内存中的区域
然而同一个堆内存中的区域能够同时被多个指针所指向
var obj1 = {
name:'tom',
age:13,
gender:'male'
}
var obj2 = {
name:'tom',
age:13,
gender:'male'
}
var obj3 = obj1;
console.log(obj1 == obj2); // false
console.log(obj1 === obj2); // false
console.log(obj1 == obj3); // true
console.log(obj1 === obj3); // true
6) 函数的外部属性 -> 只有在函数外部能够拜访到的属性
- 形参
接管参数的快捷方式 -
arguments【类数组对象】
以后函数承受的所有参数所存储的中央{ '0': 'tom', '1': '13', '2': 'male', length:3 // 只有在浏览器打印时才显示 } callee 指向以后的函数 将类数组对象转换为数组
*3. this
以后函数执行时所依赖的环境
nodejs -> global 对象
浏览器 -> window 对象
this 的指向性问题
能够依据函数的调用形式来判断
函数名(实参列表);
函数名.call(this, 实参列表);
函数名.apply(this, 实参数组);
1、以 () 形式调用函数
如果函数名的右边没有对象,则 this 指向全局
function test(){console.log(this);
}
test(); // 函数形式调用
nodejs -> global 对象
浏览器 -> window 对象 =window.test()
如果函数名的右边有对象,则 this 指向该对象
var obj1 = {
name:'tom',
sayName:function(){console.log(this.name);
}
}
var obj2 = {
name:'terry',
sayName:function(){console.log(this.name);
}
}
// 以办法形式调用
obj1.sayName(); // this 指向了 obj1 对象 tom
obj2.sayName(); // this 指向了 obj2 对象 terry
2、以 call 和 apply 的形式调用
更改 this 的指向
var obj1 = {
money:'有钱',
pay:function(){console.log(this.money);
}
}
var obj2 = {money:'没钱'}
obj1.pay(); // 有钱
obj1.pay.call(obj2); // 通过 call()将 this 指向 obj2 没钱
obj1.pay.apply(obj2); // 通过 apply()将 this 指向 obj2 没钱
3、箭头函数的 this 指向内部函数的 this
function(){} es5
()=>{} es6
7) 闭包
函数外部的函数
function test(){function a(){}}
function test(){
var name = 'tom';
function a(){return name;}
return a();}
var res = test();
console.log(res); // tom
function test(){
var name = 'tom';
console.log(age,'-----'); //age--undefined
function a(){
var age = 13;
return name;
}
return a();}
var res = test();
console.log(res);
外部函数能够拜访内部函数中的属性,然而内部函数不能拜访外部函数的属性
8) 匿名函数和自执行函数
匿名函数:没有名字的函数
function(){}
自执行函数:会主动执行的函数 --- 只执行一次
(function(){}) ()
函数对象
(function(){console.log(1);
})(); // 1
(function(name,age){console.log(name);
console.log(age);
})('zhangsan',13); // zhangsan 13
9) 办法
函数作为对象的属性,将该函数叫做对象的办法
var obj = new Object();
obj.name="jerry";
obj.sayName = function(){ // 办法
console.log(obj.name);
};
obj.sayName(); // 调用对象的办法
10)作用域
1. 全局作用域
- 页面关上时创立,页面敞开时销毁
- 有一个全局对象 window-- 代表浏览器窗口,由浏览器创立,能够间接应用
- 全局中创立的变量都会作为 window 对象的属性保留
全局中创立的函数都会作为 window 对象的办法保留
- 域中变量都为全局变量,页面任意局部均可拜访
var a=1;
console.log(window.a);
function fun(){}
window.fun();
2. 函数作用域
- 调用函数时创立,函数执行完结则销毁
- 每调用一次函数就会创立一个新的作用域
- 函数作用域中能够拜访全局变量
- 在函数作用域中创立变量,会先在本身作用域寻找,无则在上一级作用域寻找,直到全局作用域,若仍旧无,则会报错 ReferenceError
- 函数作用域中想拜访全局变量 -- window.a
- 有变量晋升 -- var 申明变量会提前, 有函数晋升
- 函数内变量未用 var 申明,则是全局变量
- 定义形参相当于在函数作用域中申明了变量
eg:
1>
var a = 10;
function fun(){
var a = 20;
function func2(){console.log(a); //a = 20
console.log(window.a) //a = 10
}
fun2();}
fun();
2>
var c =10;
function fun(){console.log(c);
c=20;
d=100;
}
fun(); //c=10 -- 找全局
console.log(c); //c=20 -- 函数内 c 未用 var 申明,是全局变量
console.log(d); //d = 100 -- 可拜访,因为 d 是全局
3>
var e = 10;
function fun(e){
//var e;定义形参即申明变量
console.log(e);
}
fun(); //underfined
1、构造函数和一般函数的区别
1) 首字母
2) 调用形式
构造函数通过 new 关键字调用
var obj = new Object();
new Vue();
一般函数间接调用
function sayName(){xxx}
sayName();
2、函数应用 () 和不应用 () 的区别
应用(),示意调用以后函数,并返回函数的返回值
不应用(), 示意一个指向以后函数的指针
如何将一个函数赋值给一个变量,再将变量放入到对象中?错误代码:function test(){console.log(1);
return 'hello world';
}
var a = test();
var obj = {name:a}
console.log(obj); // 1 {name:'hello world'}
正确代码:function test(){console.log(1);
return 'hello world';
}
var a = test;
var obj = {name:a}
console.log(obj); // {name:[Function: test]}
3、return 与 console.log()的区别
函数应用 return 之后才会有返回值
函数应用 console.log 是没有返回值的
function test(){console.log(1);
}
function fun(){return 2;}
var a = test();
var b = fun();
console.log(a); // 1 undefined
console.log(b); // 2