1、普通函数
//函数声明 (会有变量提升)----名字名是myfunc //arguments.callee.name获取函数名的方法
function myfunc(){
console.log(arguments.callee.name) // myfunc
}
myfunc();
//函数表达式 ---- 名字名是fun
var fun=function(){
console.log(arguments.callee.name) //函数名fun
}
fun()
//函数申明赋给一个变量 -------函数名agree
var fun=function agree(){
console.log(arguments.callee.name) //函数名agree
}
fun()
//匿名函数
(function(){ }) //匿名函数,没有名字的函数
var a="s"; (function(a){ console.log(a) }(a)) //自动执行匿名函数,就是直接会自己调用。也可以传递参数。
//自动执行一个声明函数,注意:fn函数在外面是访问不到的。
var a="6"; (function fn(a){ alert(a); }(a))
//弹出s,其实最后的括号放在外面和放在里面都会执行。
var a="s"; (function(a){ alert(a) })(a) ;
构造器
new Function('x', 'y', 'return x * y;'); //构造器写函数
例子:var sum= new Function('x', 'y', 'return x * y;')(5,6); console.log(sum) //30 注意:第三个引号里面只能写代码块,不能写入函数等内容
new Function() //构造器写函数
var sum= new Function('x', 'y', 'return x * y;'); console.log(sum(5,6)) //30
创建对象
var person = new Object(); //创建一个Object实例
person.name = "zhangsan";
person.age = 22;
person.sayHi = function(){}
var person = { //对象字面量方式创建对象
name: "zhangsan",
age: "22",
sayHi: function(){ return this.age; }
}
person.sayHi() //age
let o = { fn:function() {}, }; o.fn() //对象字面量
var o = { fn:function getName() { alert(5); }, }; o.fn(); //只能这样调用,如果o.getName()这种是不起效果的,相当于getName取的别名fn;
var o = { getName:function getName() { alert(5); }, }; o.getName(); //只能这样调用,如果o.getName()这种是不起效果的,相当于getName取的别名fn;
var o = { fn(){ }, getName() { alert(5); }, }; o.fn(); //oes6中可以这样写 ,简写
箭头函数的写法:谷歌浏览器可以直接运行,不用编译也可以
var fn= () => 2 * 2; fn(); // 木有参数,有返回值4,省略了return的简写
var fn= x => x * 2; fn(); //有参数4,有返回值,省略了return的简写
var fn= x => { return x * 2; } //有参数4,有返回值
var fn= (x, y) => x * y //传递俩个参数,有返回值。
var fn= (x, y, ...rest) => { var i, sum = x + y; for (i=0; i<rest.length; i++){ sum += rest[i]; } return sum; } //如果多条语句就要加上大括号。
函数工厂模式
function createNewObject(name, age, job) {
let o = new Object();
o.name = name;
o.age = age;
o.job = job
o.sayName = function() {
console.log(name);
}
return o;
};
let me = createNewObject('Ethan', 24, 'java');
console.log(me.name); // Ethan //缺点,用不同的参数多次调用函数,每次偶读会返回包含3个属性和1个方法的对象。没有解决问题。
构造函数模式
//构造函数,首字母要大写
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
}
};
let p = new Person('Ethan', 24, 'java')
let p2 = new Person('Ethan2', 24, 'java')
let p3 = new Person();
let p4= new Person; //如果没有传递参数,括号可以加上也可以不加上。
console.log(p.name); // Ethan
console.log(p2.name); // Ethan2
构造函数有问题点:每次创建一个实例对象,其定义的方法都会在创建一遍。解决这个问题,可以sayName()方法放在全局。
构造函数里面:this.sayName=sayName;
全局函数: function sayName(){};
原型的出现解决了问题:
function Person(name,age){
this.name=name;
this.age=age;
}
Person.name="梨花"; //这个是实例上的属性,会屏蔽原型上的属性
Person.prototype.name="试试";
Person.prototype.study=function(){ console.log("学习")}
//对象字面量表示法:
function Person(name,age){ }
Person.prototype={
constructor:Person, //t一定要设置指向Person,如果没有设置,就会指向Object
name:'',
study:function(){},
}
原型链的继承
//通过原型来继承一个构造函数
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.study=function(){ console.log("学习")}
function Student(name,age,subject){
this.name=name;
this.age=age;
this.subject=subject;
}
Student.prototype=new Person(); //通过原型继承,父类新增原型方法/原型属性,子类都能访问到
var s1=new Student('明明',6,'math');
console.log(s1.name,s1.age,s1.subject);
s1.study();
更多继承的知识点,在下面地址可以访问
[https://www.cnblogs.com/humin/p/4556820.html](https://www.cnblogs.com/humin/p/4556820.html)
、概念:没有实际名字的函数是匿名函数。
function (){
console.log("123");
} //匿名函数,运行时,你会发现报错啦! 由于不符合语法要求,报错啦!解决方法只需要给匿名函数包裹一个括号即可.
//匿名函数在其它应用场景括号可以省略
(function (){
//由于没有执行该匿名函数,所以不会执行匿名函数体内的语句。
console.log("123");
})
//后面加一个括号就可以执行
(function (){
//此时会输出123
console.log("123");
})()
//倘若需要传值,直接将参数写到括号内即可
(function (str){
console.log(str); //'123'
})("123")
3、匿名函数的应用场景
//1、点击事件
var $dom=document.querySelector("#Dom");
$dom.onclick=function(){
alert("当点击按钮时会执行到我哦!");
}
//2、对象
var obj={
name:“李斌”,
fn:function(){
return "我叫"+this.name;
}
};
obj.fn(); //我叫李斌
//3、函数表达式
var fn=function(){
return "TMD"
}
fn();
//4、回调函数
setInterval(function(){
console.log("回调函数");
},12000);
//5、返回值
function fn(){
return function(){
return "李斌";
}
}
fn()() //李斌
//6
var arr =new Array();
for(var i=0;i<2;i++){
arr[i]=function(){
console.log(i);
}
//arr[2]();
}
arr[1](); //输出的结果为4
arr[0]();//输出的结果为4 i变量是全局的,所以都是4
//模仿块级作用域
if(true){ //条件成立,执行if代码块语句。 b没有块级作用域,所以全局变量
var b=12;//b为全局变量
}
console.log(b);//12
for(var i=0;i<2;i++){ //i也是全局作用域
console.log(i);
}
console.log(i);//3
模仿块级作用域语法:
(function(){
//私有作用域
})();
模仿块级作用域例子:
function fn(){
(function(){
var a="123";
})();
console.log(a);//报错---a is not defined
}
fn();
4、匿名函数的作用:
4-1、通过匿名函数可以实现闭包,关于闭包在后面的文章中会重点讲解。在这里简单介绍一下:闭包是可以访问在函数作用域内定义的变量的函数。若要创建一个闭包,往往都需要用到匿名函数。
4-2、模拟块级作用域,减少全局变量。执行完匿名函数,存储在内存中相对应的变量会被销毁,从而节省内存。再者,在大型多人开发的项目中,使用块级作用域,会大大降低命名冲突的问题,从而避免产生灾难性的后果。自此开发者再也不必担心搞乱全局作用域了。
4-3、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
4-4、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值