【JS函数】JS函数之普通、构造、闭包函数

自我介绍:大家好,我是吉帅振的网络日志;微信公众号:吉帅振的网络日志;前端开发工程师,工作4年,去过上海、北京,经历创业公司,进过大厂,现在郑州敲代码。

JS函数专栏

1【JS函数】JS函数之普通、构造、闭包函数

2【JS函数】JS函数之定时器函数

3【JS函数】JS函数之防抖、节流函数

4【JS函数】JS函数之排序函数,对象数组根据某属性排序

5【JS函数】JS函数之高阶函数、组合函数、函数柯里化 

一、普通函数

关于函数基础内容建议查看w3school:JavaScript 函数

二、构造函数

1.定义:

构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象

2.主要内容:

a.默认函数首字母大写

b.构造函数并没有显示返回任何东西。new 操作符会自动创建给定的类型并返回他们,当调用构造函数时,new会自动创建this对象,且类型就是构造函数类型。

c.也可以在构造函数中显示调用return.如果返回的值是一个对象,它会代替新创建的对象实例返回。如果返回的值是一个原始类型,它会被忽略,新创建的实例会被返回。  

function Person( name){
    this.name =name;
}
var p1=new Person('John');

等同于:

function person(name ){
     Object obj =new Object();
     obj.name =name;
      return obj;
}
var p1= person("John");

d.因为构造函数也是函数,所以可以直接被调用,但是它的返回值为undefine,此时构造函数里面的this对象等于全局this对象。this.name其实就是创建一个全局的变量name。在严格模式下,当你补通过new 调用Person构造函数会出现错误。

 
e.也可以在构造函数中用Object.defineProperty()方法来帮助我们初始化:

function Person( name){
    Object.defineProperty(this, "name"{
        get :function(){
           return name;
        },
         set:function (newName){
          name =newName;
        },
        enumerable :true, //可枚举,默认为false
         configurable:true //可配置
       });
}  
var p1=new Person('John');

f.在构造函数中使用原型对象      

//比直接在构造函数中写的效率要高的多
Person.prototype.sayName= function(){
    console.log(this.name);
};


但是如果方法比较多的话,大多人会采用一种更简洁的方法:直接使用一个对象字面形式替换原型对象,如下:      

Person.prototype ={
    sayName :function(){
        console.log(this.name);
    },
    toString :function(){
        return "[Person "+ this.name+"]" ;
    }
};


这种方式非常流行,因为你不用多次键入Person.prototype,但有一个副作用你一定要注意:

使用字面量形式改写了原型对象改变了构造函数的属性,因此他指向Object而不是Person。这是因为原型对象具有一个constructor属性,这是其他对象实例所没有的。当一个函数被创建时,它的prototype属性也被创建,且该原型对象的constructor属性指向该函数。当使用对象字面量形式改写原型对象时,其constructor属性将被置为泛用对象Object.为了避免这一点,需要在改写原型对象的时候手动重置constructor,如下:

Person.prototype ={
    constructor :Person,
    sayName :function(){
        console.log(this.name);
    },        
    toString :function(){
        return "[Person "+ this.name+"]" ;
    }
};

//再次测试:
p1.constructor===Person
//true 
p1.constructor===Object
//false
p1 instanceof Person
//true

三、闭包函数

1.定义:

闭包函数指有权访问另一个函数作用域中的变量的函数。在本质上,闭包就是将函数内部和函数外部连接起来的桥梁。闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。

2.主要内容:

要理解JavaScript闭包,就要先理解JavaScript的变量作用域。
变量的作用域有两种:全局的和局部的(全局变量和局部变量)
JavaScript中,在函数内部可以直接读取到全局变量。

var n=10
function fn(){
    alert(n)
}
fn()      //10

而在函数外部无法读取到函数内部的变量。

function fn(){
    var n=10;
}
fn()
alert(n)   //n is not defined    函数外部无法读取到函数内部的n


注意:函数内部使用var声明变量的时候,这个变量是局部变量,如果不使用var,那么这个变量就是一个全局变量。

例如:
function fn(){
    n=10;
}
fn()
alert(n)   //10
另外,函数的参数也是局部性的,只在函数内部起作用。

在正常情况下,我们是无法得到函数内部的局部变量的,只有变通方法才可以——在函数内部再声明一个函数。

function f1(){
    var n=10;
    function f2(){
        alert(n)
    }
}

f2函数可以得到f1函数内的所有局部变量,但是f1函数却无法得到f2函数内部的局部变量——JavaScript语言特有的“链式作用域”结构。(即子对象会一级一级地向上寻找所有父对象的变量),所以,父对象的所有变量,对于子对象都是可见的。

f2函数可以获取到父级函数f1的局部变量,那么如果把f2()函数返回,在函数f1外部就可以访问到f1()函数内部的变量了。

例如:
function f1(){
    var n=10;
    function f2(){
        alert(n)
    }
    return f2()
}
f1()           //页面弹出10

例子中的f2()函数就是一个闭包函数。

3.用途

(1)可以读取父级作用域函数内部的变量;

(2)让变量的值始终保存在内存中(让局部变量变成全局变量),不被垃圾回收机制清除。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值