一、函数function
- 函数也是一个对象,函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)。
- 函数中可以保存一些代码在需要的时候调用。
二、 使用构造函数来创建一个函数对象
我们实际开发中很少使用构造函数来创建函数对象
var fun=new Function();
//构造函数来创建函数对象
- 使用typeof检查一个函数对象时,会返回function。
- 可以将要封装的代码以字符串的形式传递给构造函数。
var fun=new Function("console.log('Hello 这是我的第一个函数');");
-
封装到函数中的代码不会立即执行
-
函数中的代码会在函数调用的时候执行
-
调用函数语法:函数对象()
-
当调用函数时,函数中封装的代码会按照顺序执行
var fun=new Function("console.log('Hello 这是我的第一个函数');");
fun();//调用函数
结果:Hello 这是我的第一个函数
三、使用函数声明来创建函数
语法:
function 函数名([形参1,形参2...形参n]){
语句...(需要封装的代码)
}
语法:
function fun2(){
console.log('Hello 这是我的第二个函数');
}
//调用fun2
fun2();
四、使用函数表达式来创建一个函数
var 函数名= function([形参1,形参2...形参n]){
语句...(需要封装的代码);
}
function(){
console.log("我是一个匿名函数中封装的代码");
}
先创建一个匿名函数,然后定义一个变量fun3,然后将匿名函数对象赋值给变量。
//定义变量fun3保存函数对象
var fun3=function(){
console.log("我是一个匿名函数中封装的代码");
}
fun3();
五、函数的参数
- 可以在函数的()中来指定一个或多个形式参数,多个形参之间用逗号隔开,声明形参相当于在函数内部声明了对应的变量,但是并不赋值。
function sum(a,b){
console.log(a+b);
}
- 在调用函数时,可以在()中指定实际参数。实参将会赋值给对应的形参。
sum(1,2);//调用函数sum,指定实参
- 调用函数时解析器不会检查实参的类型,所以要注意,是否有可能会接收到非法的参数,可以对参数类型进行检查。
- 调用函数时,解析器也不会检查实参的数量,多余实参不会被赋值。
- 如果实参的数量少于形参的数量,则没有对应实参的新参将是undefined。
- 函数的实参可以是任意的数据类型。
六、函数的返回值return
- 可以使用return来设置函数的返回值
2. 语法: return 值(变量); - return后的值将会作为函数的执行结果返回,可以定义一个变量来接收这个结果。
- 在函数中,return后的语句都不会执行
function sum(a,b,c){
var d=a+b+c;
return d;不写
}
//调用函数
//变量result的值就是函数的执行结果
//函数返回什么result的值就是什么
var result=sum(1,2,3);
console.log(result);
- 如果return语句后不跟任何值就相当于返回一个undefined。不写也是undefined。
5. return后可以返回任意类型的值。也可以是一个对象
function people(){
return {name:"lili"};
}
var a= people();//函数people作为实参传值
console.log(a);
还可以是一个函数
七、实参可以是任何值
- 实参可以是任意的数据类型,也可以是一个对象,当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递实参
function people(o){//o是形参,obj是一个实参对象,obj将赋值给o
console.log("我叫"+o.name+",我今年"+o.age+"岁了,我是"+o.gender+"生");
}
var obj = {
name:"lili",
age:22,
gender:"女"
};
people(obj);//将一个对象obj作为实参传入
- 实参可以是一堆对象,也可以是一个函数
function people(o){//o是形参,obj是一个实参对象,obj将赋值给o
console.log("我叫"+o.name+",我今年"+o.age+"岁了,我是"+o.gender+"生");
}
var obj = {
name:"lili",
age:22,
gender:"女"
};
people(obj);//将一个对象obj作为实参传入
function fun(result){
//console.log("这是一个函数作为实参的例子:"+result);
result(obj);
}
fun(people);//函数people作为实参传值
- 可以把一个匿名函数作为实参传递给另外一个函数。
function test(){}
test()是调用函数对象
fun(test(10))相当于fun这个函数对象调用了test函数以10为形参的返回结果
test是函数对象,相当于与直接使用这个函数对象
function fun1(){
return {name:"lili"};
}
function fun2(a){
console.log( a.name); //lili
}
fun2(fun1());//调用fun1函数对象的返回值
八、break和continue和return
- break可以退出当前循环,当前循环次数后的都不执行了。
- continue相当于跳过当次循环,跳过当次循环之后的还要继续执行。
- return可以结束整个函数
九、立即执行函数
function(){
console.log("我是一个匿名函数中封装的代码");
}
//给匿名函数加一个括号表示一个整体
//在这个函数对象后面再加一个括号,表示调用这个函数对象,这是一个立即执行函数。
(function(){
console.log("我是一个匿名函数中封装的代码");
})();
立即执行函数:函数定义完,立即被调用,这种函数叫做立即执行函数,立即执行函数往往只会执行一次。
十、构造函数 类
- 创建一个构造函数,专门用来创建Person对象,对于都是对象里面的不同类型。
- 构造函数就是一个普通的函数,创建方式和普通的没有区别,不同的是构造函数习惯上首字母需要大写
- 普通函数就是直接调用,而构造函数需要使用new关键字来调用
function Person(){
}
//new构造一个新对象
var per= new Person();
console.log(per);//{}
- 构造函数的执行流程:
(1)立刻创建一个新对象
(2)将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象。per保存着新建的这个对象的地址,this指向新建的对象,就是per对象。
(3)逐行执行函数中的代码
(4)将新键的对象作为返回值返回`
function Person(){
this.name="孙悟空";
this.age=18;
this.sayName=function(){
console.log(this.name);
};
}
//new构造一个新对象
var per= new Person();
console.log(per);
传值:
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=function(){
console.log(this.name);
};
}
//new构造一个新对象
var per= new Person("孙悟空",18);
var per2= new Person("猪八戒",28);
console.log(per);
- 使用同一个构造函数创建的对象,我们称为一类对象,例如per1、per2是一类对象,都是person类的,也将一个构造函数称为一个类。
- 我们将通过一个构造函数创建的对象,称为是该类的实例。例如per是Person类的实例。
- 使用instanceof可以检查一个对象是否是一个实例。语法:对象 instanceof 构造函数如果是返回true,不是返回false
console.log(per instanceof Person);
-
所有的对象都是Object的后代,所以任何对象和Object做instanceof检查时都会返回true。
-
创建一个Person构造函数,在Person构造函数中,为每一个对象都添加了一个sayName方法。
-
目前我们的方法是在构造函数内部创建的,也就是构造函数每执行一次就会创建一个新的sayName方法,也是所有实例的sayName都是唯一的。
-
这样就导致构造函数执行一次就会创建一个新的方法,执行多少次就会创建多少个新的方法,而这些方法都是一样的,这是完全没有必要的。
-
将sayName方法放在全局作用域中定义
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=fun;
}
//将sayName方法放在全局作用域中定义
function fun(){
console.log(this.name);
};
//new构造一个新对象
var per= new Person("孙悟空",18);
var per2= new Person("猪八戒",28);
console.log(per);
- 但是将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域也不安全。
- 接学习笔记九-原型
function Person(name,age){
this.name=name;
this.age=age;
}
//new构造一个新对象
var per= new Person("孙悟空",18);
var per2= new Person("猪八戒",28);
Person.prototype.sayName=function(){
console.log(this.name);
}
console.log(per.sayName());