zoukankan      html  css  js  c++  java
  • 【设计模式+原型理解】第四章:函数的三种角色+原型链终结版

    一、函数的三种角色

      1)作为普通函数

      2)作为对象

      3)作为类

    ps:可以同时存在,之间没有任何冲突

    二、怎么理解函数的三种角色

      这三种角色可以同时存在,没有任何冲突,举个例子

    // 这三种角色是没有冲突的,看下面的例子
    function Fn1() { // 这时候,Fn就是一个普通函数,形参赋值,预解释,代码执行
        var num = 500
        this.x = 100;
    }
    Fn.prototype.getX = function () {
        console.log(this.x);
    };
    Fn.aaa = 1000; // 这时候,Fn就是作为一个对象(有私有属性,有方法,还有原型)
    var f = new Fn; // 这时候,Fn就是一个类,可以通过new创建对象 ,this指向的是f!!
    
    console.log(f.num); //->undefined   这个时候,Fn就是一个类,num是Fn作为普通函数才有用,num跟类完全没关系
    console.log(f.aaa); //->undefined   这个时候,Fn就是一个类,aaa是Fn作为对象才有用,aaa跟类完全没有关系
    
    var res = Fn();
    console.log(res); //->undefined   这个时候,Fn就是一个普通函数,函数里没返回值,this指向的是window!!!!!!!!
    

      上面的例子完美的解释了,函数三种角色真的没有任何联系。
      感觉函数真的是模拟了真实人生,就好比我带着我爸妈,带着我闺女,我作为人类、作为父亲、作为儿子,没有任何冲突,该干嘛干嘛!!

      上面的代码,可以打印一下Fn函数里面到底有什么东西。

    dir(Fn)
    

      输出信息如下:

      可以看到,Fn作为对象,有自己的属性值(arguments、caller、length、name、prototype、__proto__)

    三、深入理解原型 

      其实,上面的一二两点,都是总结,你有想过,为什么函数会存在三种角色吗?其实,想要理解函数的三种角色,就必须深入探索一个完整的原型链的工作方式。

      先看一个例子,帮助我们理解函数的三种角色

    function Fn() {
        this.x = 100;
    }
    Fn.prototype.getX = function () {
        console.log(this.x);
    };
    var f = new Fn;
    console.log(f instanceof Fn); //->true
    console.log(f instanceof Object); //->true
    

       简单说明一下上面的代码,使用的原型继承的方式,首先声明定义一个Fn函数类,然后再Fn函数类的原型上添加一个公有的方法getX,之后,使用new关键字创建一个Fn函数类的一个实例,从而f继承了Fn的私有+公有的方法。

      很明显,f instanceof Fn 是true的,因为f是通过new Fn来创建出来的,但是为什么f instanceof Object 也是为true呢?要回答这个问题,得理解下面的话。

      1)Function是浏览器内置的函数类(Function也是对象),所有的函数都是Function类的一个实例

      2)Object是浏览器内置的对象类,所有对象都是Object类的一个实例

      3)所有实例,都是对象数据类型

      4)根据1、2两点,可以知道,上面定义的Fn函数,是Function类的一个实例,那么Fn函数其实就是一个实例,根据第3点,Fn函数就是一个对象数据类型;

          同理,因为Object对象类是一个类,类其实也是就函数,所以Object对象类是Function类的一个实例。

      5)根据第3、4点,可以知道,内置类Function、内置类Object、函数Fn它们都是对象,那么是对象会拥有__proto__属性,所以它们都拥有__proto__属性。

     

    四、第三点中代码的完整原型链

       值得注意的是,上图中,Function.prototype其实并不是对象,是函数数据类型,非常坑爹!其实它叫做anonymous(匿名函数),没有实际意义的一个函数,但是操作起来跟对象一模一样。

       打印Function.prototype,样子如下所示:

    五、总结

       函数在整个JS中是最复杂也是最重要的知识,一个函数存在多面性,而且相互不冲突:

       -> “函数”:它本身是一个函数,执行的时候形成私有作用域(闭包),形参赋值、预解释、代码执行、执行完后栈内存销毁/不销毁;

       -> “类”:    它有自己的实例,也有一个叫做prototoype属性是自己的原型;

       -> “普通对象”:和var obj = {} 中的obj一样,就是一个普通的对象,它作为对象有自己的私有属性,也可以通过__proto__找到Function.ptototype。

  • 相关阅读:
    c# datagridview 设置某行不可见解决办法
    MessageBox, MessageBoxBurttons, MessageBoxIcon 详细解析
    c# 项目带皮肤一起打包发布解决办法
    Winform DataGridView CheckBoxColumn c# 单选 解决方案
    机器学习 课程笔记
    机器学习-review-1 线性回归
    Office升级到2013版后无法登录微软账号问题
    Address already in use: make_sock: could not bind to address 0.0.0.0:80
    PHP的数组排序函数
    事件与委托例子
  • 原文地址:https://www.cnblogs.com/pengshengguang/p/10817033.html
Copyright © 2011-2022 走看看