zoukankan      html  css  js  c++  java
  • js---闭包和面向对象编程

    这两个概念理解起来不容易,翻查了很多资料,几乎耗费了我一天的时间来理解它,感觉自己都快走火入魔了。不过最终有所了悟,一番付出还是有所收获的。

    (1)闭包概念

    很多书上关于闭包的定义直接阅读的话很难理解,下面我通过实例来讲解这个概念。

    1、首先,我们必须了解变量的作用于问题。js的作用于无外乎有两种,一种是全局变量(可以在全局范围内被调用),一种是局部变量(一般在函数内声明,正常情况下只能在函数内调用)。

    js语言的特俗之处就在于函数内部可以读取全局变量。(需要注意的是,在函数内部定义变量一定要用到var,否则你定义的就是全局变量)

    2、一般情况下,从函数外部无法读取函数内部的局部变量。但是特殊情况下,通过变通的方式可以实现。

    我们可以在函数内部在定义一个函数。

    function f1() {

    var n = 999;

    function f2() {

    alert(n);

    return f2;

    }

    var result = f1();

    result();

    上述代码中,f2函数就是闭包。我给出的定义是能够读取函数内部变量的函数就叫闭包。

    3、闭包的用途

    .可以读取函数内部的变量

    .让这些变量的值始终保持在内存中。

    function f1() {

    var n=999;

    nAdd = function() {n+=1};

    function f2() {

    alert(n);

    return f2;

    var result = f1();//运行之后返回f2,此时n=1000.注意f2函数并未运行,也就是不会运行alert(n);

    result();//运行完后,变量n仍然保存在内存中,值为999

    nAdd();//全局函数,n自加1;

    result();

    result实际上就是等于函数f2.它一共运行了2次,一次是999,一次是1000.这证明了函数f1中的局部变量n一直保存在内存中,并没有在调用后被自动清理机制自动清除。

    为什么会这样?原因就在与f2被赋予给一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终保存在内存中,不会在调用结束后被垃圾回收机制回收。

    至于nAdd = function() {n+=1}这一行,没有使用var关键字,因此nAdd是一个全局变量而不一个局部变量。这样函数可以在外部对函数内部的局部变量进行操作。

    (2)面向对象编程:封装

    如果我们要把“属性”和“方法”封装成一个对象,甚至从原型对象生成一个实例对象,我们该怎么做?下面我介绍封装方法的演变过程。

    1、生成对象的原始模式

    把手机看成一个对象,他有类型和颜色两个属性

    var shouji = {

    type = “”,

    color = “”

    根据这个原型对象的规格,生成两个实例。

    var shouji1 = {};

    shouji1.type = “苹果”;

    shouji1.color = “red”;

    var shouji2 = {};

    shouji2.type = “华为”;

    shouji2.color = “blue”;

    上面是最简单的封装,缺点:多生成几个实力写起来就会非常麻烦,实力和原型之间没有什么办法看出什么联系。

    2、原始模式的改进

    通过构造一个函数解决函数重复问题。

    function Shouji(type,color) {

    return {

    type:type,

    color:color

    生成实例

    var shouji1 =new Shouji(“苹果”,“red”);

    var shouji2 =new Shouji(“华为”,“blue”);

    shouji1和shouji2之间没有内在练习,不能反映出它们是同一个原型对象的实例。

    3、构造函数模式

    构造函数就是普通函数,除了按约定首字母大写,内部使用了this变量。对构造函数使用new运算符就能生成实例,并且this对象会绑定在实例对象上。

    例:function Shouji(type,color) {

    this.type = type;

    this.color = color;

    生成实例

    var shouji1 =new Shouji(“苹果”,“red”);

    var shouji2 =new Shouji(“华为”,“blue”);

    这时shouji1和shouji2自动含有一个construcor属性,指向他们的构造函数。

    shouji1.constructor == Shouji;

    shouji2.constructor == Shouji;

    如果上述对象添加一个shouji添加一个不变的属性“gongneng”和一个“internet”上网功能,那么原型对象就变成下面这个样子。

    function Shouji(type,color) {

    this.type = type;

    this.color = color;

    this.gongneng = “打电话”;

    this.internet = function(){alert(“吃老鼠”)}

    生成实例

    var shouji1 =new Shouji(“苹果”,“red”);

    var shouji2 =new Shouji(“华为”,“blue”);

    对于每一个实力对象,gongneng属性和internet()方法都是一模一样的内容,每次生成一个实力都必须重复同样的内容,多占用一些内容这样既不环保也缺乏效率。

    能不能让gongneng属性和internet方法在内存中只生成一次,然后所有实例都指向那个内存地址?以下的方式可以。

    4、prototype模式

    js规定每一个构造函数都有一个prototype属性,指向另一个对象。这个对象所有属性和方法都会被构造函数的实例继承。

    我们可以把这些不变的属性和方法直接定义在prototype对象上。

    function Shouji(type,color) {

    this.type = type;

    this.color = color;

    Shouji.prototype.gongneng = “猫科动物”;
    Shouji.prototype.nternet = function(){alert(“吃老鼠”)};

  • 相关阅读:
    chrome安装HostAdmin app
    Python编码问题
    Elasticsearch利用scroll查询获取所有数据
    oracle不小心更新了数据库中的所有内容后的恢复
    git误提交了项目文件和配置文件的恢复方法
    生成banner的网站
    去除字符串中的emoji字符
    爬虫从网页中去取的数据中包含 空格
    高版本的jdk编译过的项目移到低版本的JDK的eclipse中出错的问题
    java爬虫爬取的html内容中空格( )变为问号“?”的解决方法
  • 原文地址:https://www.cnblogs.com/jiandanshishu/p/12953321.html
Copyright © 2011-2022 走看看