• Javascript prototype 元语言编程


    昨天发了一篇小文Javascript 匿名函数的一种应用:封装,没想到来自Tony Zhou的第一个回复就把我带入到Javascript的元编程领域。我以前使用过的语言中Python和lua是支持元编程的。他们都使用了一种类似元表的结构来实现元编程。js也有同样的机制,尝试之后发现,一点都不逊色。而js的元表就是prototype。先来看一段代码:

    function A()
    {
    this.x = 10;
    this.add = function(s)
    { this.x += s; }
    }
    a1 = new A();
    alert(a1.x)//output 10
    a1.add(10)
    alert(a1.x)//output 20
    a1.sub = function(s)
    { this.x -= s; }
    a1.sub(10)
    alert(a1.x)//output 10

    上面的代码演示了js一个很基本的应用,允许实例动态增加成员。但是如果我希望每一A的实例都增加“sub”这个方法怎么办呢,显然在每次创建时自己增加是很麻烦的。现在prototype可以出场了:

     

    A.prototype.sub = function(s)

    {

      this.x -= s;

    }

     

    好了从这里开始所有A的实例包括已经创建的实例都自动增加了“sub”这个方法。

    回到上一篇文章最后我提的问题:JS能够实现继承吗?这个问题也找到了答案,还是prototype。下面来看另外一段代码:

    //基类
    function A()
    {
    this.x = 10;
    this.add = function(y)
    { this.x += y }
    }


    function B()
    {
    this.y = 10;
    this.sub = function(x)
    { this.y -= x; }
    }
    B.prototype = new A();//在这里B继承了A


    function C()
    {
    this.z = 10;
    this.mul = function(s)
    { this.z *= s; }
    }
    C.prototype = new B();//在这里C继承了B


    function printProt(tb)
    {
    str="Table = {\n";
    for(var k in tb)
    {
    str += k + ":" + tb[k] + "\n";
    }
    str += "\n}";
    alert(str);
    }

    printProt(C);//打印C的元表
    x = new C();

    //下面显示x的继承关系
    alert("x is a C:" + (x instanceof C));
    alert("x is a B:" + (x instanceof B));
    alert("x is a A:" + (x instanceof A));


    到这里一切似乎都明白了,但是我还是有点小疑问。我在打印元表时发现,如果不显示使用prototype的话,默认它是空的,例如:上面代码中的类A的成员“x”,“add”就不在A.prototype中。而Array等内建类型的元表默认也是空的。看见prototype在JS的世界里只是一个可选的技术,而且从一些文章来看,好像也并不收到推崇。

    本文旨在解答Javascript的继承问题,虽然使用Javascript未必会用到继承,但是多了解手头工具的特性总是好的。

    (最后我忍不住又有了个问题:

    function F1(obj)

    {

      obj.F2(); 

    上面的函数接受一个对象,然后他认为该对象有一个叫F2的函数可供调用,但是这个对象很可能没有这个函数,于是F1需要对他进行检查:

    function F1(obj)

    {

      if(obj.F)

        obj.F2(); 

    }

    这种写法到处都能见到,管用但是丑陋。是不是有一种方法,当访问不存在的成员时,提供一种默认行为,而不是到处去检查? 

    ) 


  • 相关阅读:
    caffe学习笔记(1)安装
    windows下遍历文件夹
    图像处理之OpenCV
    OpenCV的安装和使用
    使用cpplint检测代码规范
    图像处理之原理
    Python 在cmd中import模块成功,但是在jupyter notebook中No module xxx found
    Win10上使用VS2015编译Caffe2
    Win10, VS2017环境下OpenCV3.4.2的配置
    C++ main函数的参数
  • 原文地址:https://www.cnblogs.com/sillyemperor/p/1766218.html
Copyright © 2020-2023  润新知