函数多种写法,匿名函数、构造函数

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),这时一定要小心,不要随便改变父函数内部变量的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值