[原创]类似Java语法的Javascript框架js5,实现jpackage,jimport,jextends,jclass,jnew

终于到java的关键字package,import,extends,class,new实现了一遍。

代码为证:

 

 

var Js5 = {version:"5.0.0"};
var __cpackage__;
var __gclasses__ = {};
var __iclasses__ = {};
var __imports__ = [];

Js5.apply = function(o, c) {
    if (o && c && typeof c == 'object') {
        for (var p in c) {
            o[p] = c[p];
        }
    }
    return o;
};

(function() {
    var toString = Object.prototype.toString,
        oc = Object.prototype.constructor;

    Js5.apply(Js5, {
        applyIf : function(o, c) {
            if (o) {
                for (var p in c) {
                    if (!Js5.isDefined(o[p])) {
                        o[p] = c[p];
                    }
                }
            }
            return o;
        },
        override: function(origclass, overrides) {
            if (overrides) {
                var p = origclass.prototype;
                Js5.apply(p, overrides);
            }
        },
        /*override : function(origclass, overrides) {
         if (overrides) {
         var p = origclass.prototype;
         overrides = overrides(p.superclass);

         Js5.apply(p, overrides);

         if (Js5.isIE && overrides.hasOwnProperty('toString')) {
         p.toString = overrides.toString;
         }
         }

         },*/
        isFunction : function(v) {
            return toString.apply(v) === '[object Function]';
        },
        isString : function(v) {
            return typeof v === 'string';
        },
        isBoolean : function(v) {
            return typeof v === 'boolean';
        },
        isElement : function(v) {
            return !!v && v.tagName;
        },
        isDefined : function(v) {
            return typeof v !== 'undefined';
        },
        isObject : function(v) {
            return !!v && Object.prototype.toString.call(v) === '[object Object]';
        },
        isDate : function(v) {
            return toString.apply(v) === '[object Date]';
        },
        isPrimitive : function(v) {
            return Js5.isString(v) || Js5.isNumber(v) || Js5.isBoolean(v);
        },
        isNumber : function(v) {
            return typeof v === 'number' && isFinite(v);
        },
        isEmpty : function(v, allowBlank) {
            return v === null || v === undefined || ((Js5.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
        },
        isArray : function(v) {
            return toString.apply(v) === '[object Array]';
        },
        isIterable : function(v) {
            //check for array or arguments
            if (Js5.isArray(v) || v.callee) {
                return true;
            }
            //check for node list type
            if (/NodeList|HTMLCollection/.test(toString.call(v))) {
                return true;
            }
            //NodeList has an item and length property
            //IXMLDOMNodeList has nextNode method, needs to be checked first.
            return ((typeof v.nextNode != 'undefined' || v.item) && Js5.isNumber(v.length));
        },
        each : function(array, fn, scope) {
            if (Js5.isEmpty(array, true)) {
                return [];
            }
            if (!Js5.isIterable(array) || Js5.isPrimitive(array)) {
                array = [array];
            }
            for (var i = 0, len = array.length; i < len; i++) {
                if (fn.call(scope || array[i], array[i], i, array) === false) {
                    return i;
                }
            }
            return [];
        },
        namespace : function() {
            var o, d;
            Js5.each(arguments, function(v) {
                d = v.split(".");
                o = window[d[0]] = window[d[0]] || {};
                Js5.each(d.slice(1), function(v2) {
                    o = o[v2] = o[v2] || {};
                });
            });
            return o;
        },
        nameclass:function(c) {
            if (__gclasses__[c]) return __gclasses__[c];
            var d = c.split(".");
            var o = window[d[0]] = window[d[0]] || {};
            Js5.each(d.slice(1, d.length - 1), function(v2) {
                o = o[v2] = o[v2] || {};
            });
            return __gclasses__[c] = o[d[d.length - 1]];
        },
        importclass:function(c) {
            if (__gclasses__[c]) return __gclasses__[c];
            if (__iclasses__[c]) return __iclasses__[c];

            var d = c.split(".");
            var o = window[d[0]] = window[d[0]] || {};
            var name = d[d.length - 1];
            Js5.each(d.slice(1, d.length - 1), function(v2) {
                o = o[v2] = o[v2] || {};
            });
            if (o[name]) {
                o = __gclasses__[c] = o[name];
            } else {
                Js5.each(__imports__, function(i) {
                    if ((o = i[name])) {
                        return false;
                    }
                });

                __iclasses__[c] = o;
            }

            return o;
        }
    });
})();


/**
 * p1:String ==>package name
 * p2..p-1,Object ==>imports
 * p-1,function ==> package body
 */
function jpackage() {
    var l = arguments.length,i = 0;
    if (l == 0) return;
    var pkf = arguments[l - 1];
    pkf.$Define = true;

    if (Js5.isString(arguments[0])) {
        __cpackage__ = Js5.namespace(arguments[0]);
        i = 1;
    } else {
        __cpackage__ = window;
        i = 0;
    }
    var args = [],vs,ip;
    Js5.each(Array.prototype.slice.call(arguments, i, l - 1), function(v) {
        if (Js5.isString(v)) {
            vs = v.split(";");
            Js5.each(vs, function(v2) {
                if (v2.substr(-2) == ".*") {
                    ip = Js5.namespace(v2.substring(0, v2.length - 2));
                    __imports__.push(ip);
                    args.push(ip);
                } else {
                    args.push(Js5.importclass(v2));
                }
            });
        } else if (Js5.isArray(v)) {
            args = args.concat(v);
        } else {
            args.push(v);
        }
    });
    pkf.apply(__cpackage__, args);

    __cpackage__ = null;
    __imports__ = [];
    __iclasses__ = {};

}

function jimport() {
    var args = [],vs,ip;
    __imports__ = [];
    __iclasses__ = {};
    if (jimport.caller) {
        jimport.caller.$Define = true;
    }
    Js5.each(arguments, function(v) {
        if (Js5.isString(v)) {
            vs = v.split(";");
            Js5.each(vs, function(v2) {
                if (v2.substr(-2) == ".*") {
                    ip = Js5.namespace(v2.substring(0, v2.length - 2));
                    __imports__.push(ip);
                    args.push(ip);
                } else {
                    args.push(Js5.importclass(v2));
                }
            });
        } else if (Js5.isArray(v)) {
            args = args.concat(v);
        } else {
            args.push(v);
        }
    });
    return args;
}

function jextends() {

    var oc = Object.prototype.constructor;
    var l = arguments.length;
    var sb = arguments[0];
    var sp = arguments[1];
    var mixins = [];
    var coverrides;
    if (l < 2) {
        throw new Error("[jextends] invalid arguments");
    }
    if (l == 2) {
        coverrides = sp;
        sp = sb;
    } else if (Js5.isArray(arguments[2])) {
        mixins = arguments[2];
        coverrides = sp;
        sp = sb;
        l = 2;
    } else {
        coverrides = arguments[2];
        if (l == 4) {
            mixins = arguments[3];
        }
    }
    if (Js5.isString(sp)) {
        sp = Js5.importclass(sp);
    }

    var E = function() {
    },sbp,spp = sp.prototype;
    E.prototype = spp;

    mixins.unshift(spp);

    if (Js5.isFunction(coverrides)) {
        coverrides.$Define = true;
        coverrides = coverrides.apply(this, mixins);
    }

    if (l == 2) {
        sb = coverrides.constructor != oc ? coverrides.constructor : function() {
            sp.apply(this, arguments);
        };
    }
    sbp = sb.prototype = new E();
    sbp.constructor = sb;
    sb.superclass = spp;
    if (spp.constructor == oc) {
        spp.constructor = sp;
    }

    /*sbp.superclass = (function() {
     return spp;
     });*/

    Js5.override(sb, coverrides);  // extend coverrides

    if (mixins.length > 1) {
        for (var i = 1,len = mixins.length; i < len; i++) {
            Js5.applyIf(sbp, mixins[i]);
        }
    }

    return sb;
}

/**
 * p1:String ==>class name
 * p2,String ==>same package;Object
 * p3,function ==>
 */
function jclass() {
    var l = arguments.length,i = 0;
    if (l == 0) {
        throw new Error("[jclass] invalid arguments");
    }
    if (!Js5.isString(arguments[0])) {
        throw new Error("[jclass] class name must be string");
    }
    if (l == 1) {
        return jclass.caller && jclass.caller.$Define ? __cpackage__ && __cpackage__[name] ||
            Js5.importclass(arguments[0]) : Js5.nameclass(arguments[0]);
    }

    var clf = arguments[l - 1];


    var p;
    if (l >= 3) {
        var name = arguments[1];
        if (Js5.isString(name)) {
            p = __cpackage__ && __cpackage__[name] || Js5.importclass(name);
        } else {
            p = arguments[1];
        }
    } else {
        p = Object;
    }
    if (!p) {
        throw new Error("[jclass] unrecognized parent class");
    }
    var mixins = [];

    if (l >= 4) {
        var vs;
        var mc;
        Js5.each(Array.prototype.slice.call(arguments, 2, l - 1), function(v) {
            if (Js5.isString(v)) {
                vs = v.split(",");
                Js5.each(vs, function(v2) {
                    mc = Js5.importclass(v2);
                    if (mc) {
                        mixins.push(mc.prototype);
                    }

                });

            } else {
                mixins.push(v.prototype);
            }
        });
    }

    var cls = jextends(p, clf, mixins);

    if (arguments[0]) {
        __cpackage__[arguments[0]] = cls;
    }

    return cls;
}

function jnew() {
    var l = arguments.length,i = 0;
    if (l == 0) return {};

    var args = Array.prototype.slice.call(arguments, 1);

    var name = arguments[0];

    var cls;
    if (Js5.isString(name)) {
        cls = jnew.caller && jnew.caller.$Define ?
            __cpackage__ && __cpackage__[name]
                || Js5.importclass(name) : Js5.nameclass(name);

        if (!cls) {
            throw new Error("[jnew] unrecognized class,use whole class name");
        }
    } else {
        cls = name;
    }


    /*var temp = function() {
     };

     var constructor = cls.prototype.constructor;
     var instanceCls = function() {
     return constructor.apply(this, args);
     };

     temp.prototype = cls.prototype;
     instanceCls.prototype = new temp();
     instanceCls.prototype.constructor = instanceCls;

     return new instanceCls();*/

    var obj = {};
    Js5.override(obj, cls);
    obj.__proto__ = cls.prototype;
    cls.apply(obj, args);
    return obj;
}

function jsupercall(cls, method, args) {
    var sp = Js5.isString(cls) ? jsupercall.caller && jsupercall.caller.$Define ? Js5.importclass(cls) : Js5.nameclass(cls) : cls;
    return sp.superclass[method].apply(this, args);
}

 

 

 

还有例子:

 

 

  var jui = {};

  jpackage("jui", function() {

    jclass("Component", function() {
      return {
        constructor:function(x) {
          console.log("Component:" + x);
        },
        show:function() {
          console.log("Component");
        }
      }
    });

    jclass("Container", "Component", function(_supr) {
      return {
        constructor:function(x) {
          console.log("Container:" + x);
          _supr.constructor.call(this, x);
        }
      };
    });

  });

  jpackage("jui", function() {

    jclass("Window", "Container", function(_supr) {
      return {
        show:function() {
          console.log("Window");
        }
      }
    });

  });

  jpackage("jui.form", function() {

    jimport("jui.*");

    jclass("TextField", "Component", function(_supr) {
      return {
        show:function() {
          console.log("TextField");
        }
      }
    });


  });

  jpackage("js5.util", function() {

    jclass("Observable", function(_supr) {
      return {
        constructor:function() {
          console.log("Observable.constructor");
        },
        on:function() {
          console.log("Observable.on");
        },
        show:function() {
          console.log("Observable.show");
        }
      }
    });

  });

  jpackage("jui.ex", jimport("jui.Window;jui.*;jui.form.*"), function(_W, j) {

    jclass("Window", "jui.Window", "js5.util.Observable", function(_supr, _ob) {
      return {
        constructor:function(x) {
          console.log("jui.ex.Window.constructor");
          _supr.constructor.call(this, x);
          _ob.constructor.call(this);
        },
        show:function() {
          console.log("Window Ex");
          _supr.show();
        }
      }
    });

    var MyWindow = jclass("", "jui.Window", function() {

      return {
        show:function() {
          console.log("anonymous myWindow");
        }
      }
    });


    var x = jnew("Window", "package jui.ex.Window");
    x.show();
    x.on();

    x = new MyWindow("ssssssss");
    x.show();

    jclass("jui.Window").superclass.constructor.call(this, "111111111111");


    x = jnew(jui.Window, "jui.Window : new in package, use complete class path");
    x.show();

    x = new jui.Window("jui.Window : new in package, use complete class path");
    x.show();

    x = jnew("jui.Window", "jui.Window: new in package, use complete class path");
    x.show();

    x = new j["Window"]("jui.Window: new in package, use import jui.*");
    x.show();

    x = new _W("jui.Window:  new in package, use import jui.Window");
    x.show();

    for (var i = 1; i <= 5; i++) {
      x = jnew("TextField", "jui.form.TextField  new in package,use import jui.form.*");
      x.show();
    }


  });

  var a = jextends(jui.Window, function() {
   return {
   show:function() {
   console.log("jextends show");
   }
   }
   });


  var x = jnew("jui.ex.Window", "global jui.ex.Window");
  x.show();
 

 

 

深入解析以太网接口中的BOB Smith电路设计 本文深入解析以太网接口中的BOB Smith电路设计,详细介绍了其在共模噪声抑制、浪涌防护和EMI优化中的关键作用。通过实际案例和设计要点,帮助工程师正确选择75Ω电阻和高压电容等元件,优化PCB布局,解决电压型与电流型PHY的设计差异,以及千兆与百兆以太网的特殊考量。 阅读详情

相关推荐

个人信息保护合规审计人员(中级)能力测试试卷

本文是关于个人信息保护合规审计的考试指南,包含选择题、判断题、简答题和案例分析题。选择题考察《个人信息保护法》的关键条款,如敏感信息处理、跨境传输、委托处理等合规要求。判断题测试对个人信息处理规则的理解,如撤回同意、公开信息处理等。简答题要求阐述审计流程、个人权利、委托处理义务等内容。案例分析题以互联网企业为例,分析违规行为并提出整改建议,涉及数据收集、第三方共享、自动化决策等问题。全文旨在帮助中级审计人员掌握个人信息保护的法律规定和审计实务,提升合规审计能力。

qq_41525079的博客 547

[原创]类似Java语法的Javascript框架js5(v2)

第二版本: 1.添加了 jimport 类似实现java的import关键字 2.jclass的改进: 单个参数为返回查找的类, 第一个参数为""时,产生匿名函数。 从第三个参数到倒数第二个参数为mixin,且所有的mixin将按照顺序传入类定义的闭包函数的第二个参数到最后一个参数。     附上代码:   var Js5 = {version:"5.0.0"}...

ESR 研发中心 177

学习笔记:物理信息神经网络(PINN)

PINN 的强大在于它打破了传统数值方法的限制,将神经网络的非线性拟合能力与物理方程的严谨性结合起来。它在处理高维、数据稀缺、复杂物理约束的场景下尤其出色。当然,PINN 也有收敛慢、梯度消失等挑战,比如,复杂 PDE 可能导致梯度传播困难,收敛慢(梯度消失)、于具有快速变化特征的系统,如冲击波,标准 PINN 可能精度不足,需要改进策略,比如自适应采样或多尺度特征提取。但随着研究深入,这些问题正在不断被解决。物理或化学方程为什么往往是偏微分方程?什么是物理信息神经网络(PINN)?x_%7Bi%7D。

qq_52635735的博客 1万+

安装配置管理 之 安装和配置 JPackage Java

作者:Paul Howarth,写于 2005 年 6 月 28 日修订:为 Sun Java 1.5.0 update 5 更新于 2005 年 10 月 6 日翻译:懒猫,译于 2005 年 10 月 20 日。摘要:FC4 的发行说明中建议用户尽量避免直接使用 Sun 提供的 Java RPM,并提供了从 JPackage.org 构建 Java 的途径。本文向您介绍安装 JPackag...

weixin_34026484的博客 464

手把手教你用DLP4500和海康相机搭建双目结构光系统(附完整代码获取路径)

本文详细介绍了如何利用DLP4500投影仪和海康工业相机搭建低成本双目结构光三维测量系统。从硬件选型、软件配置到结构光编码解码实现,再到三维重建全流程,提供了完整的实战指南和优化技巧,帮助用户以不到2万元的预算实现0.05mm精度的三维扫描。

weixin_32447969的博客 317

用户行为路径可视化_桑葚图(Sankey)

桑基图对用户行为路径可视化的blog学习笔记。

徐思孟的博客 3855

安装和配置 JPackage Java

作者:Paul Howarth,写于 2005 年 6 月 28 日修订:为 Sun Java 1.5.0 update 5 更新于 2005 年 10 月 6 日翻译:懒猫,译于 2005 年 10 月 20 日。摘要:FC4 的发行说明中建议用户尽量避免直接使用 Sun 提供的 Java RPM,并提供了从 JPackage.org 构建 Java 的途径。本文向您介绍安装 JPa

软件外包的出路 2459

高性能优化的本质

在很早之前,处理器性能的提升一般是通过减小元器件的尺寸,增加元器件的数量,提高主频来实现,这也是摩尔定律所说的,但是由于功耗的影响,主频不能一直增加。后来,由于英伟达的GPU的并行计算的出现,逐渐打破摩尔定律,人们利用多核,SIMD,SIMT来处理大量相同计算的数据,这极大的提高了效率。计算机的算力得到了巨大的提升,但是并行是困难的,对于有数据依赖的程序来说,处理并行是一件及其困难的事,但对于一些简单的数学库的计算,并行的实现相对简单。

发狂的小花的博客 274

jpackage打包java项目为exe及安装包(模块化javafx版)

1、构建基于模块的javafx项目,并由maven管理。添加maven插件javafx-maven-plugin,并使用命令mvn javafx:jlink生成runtime。 2、基于步骤1中的runtime,使用jpackage生成exe启动器,命令示例: ./jpackage.exe --type app-image -n TM -m vision/tm.vision.ui.ApplicationEntry --runtime-image F:\code\TM_Vision\target\tm

IamJavaStar的专栏 4374

Python控制TEMI1000/TEMI1500测试温箱

该温箱是我司从昆山振弘检测设备有限公司采购的TEMI 1000,但是控制器用的是韩国的,关于控温箱这个项目,可参考的资料仅有一份官方的manual,里面包含一些命令格式。只要你有温箱,就应该可以向厂家索取该文档。该温箱的通讯接口只有一个RS232接口,要想实现远程控制,需要有串口转USB的线;类似于下图所以,想依靠python来与之进行通信,还是要通过python 的pyserial库,关于怎么安装pyserial,过于简单,这里不做赘述,可自行百度。

xgh1951的博客 1万+

基于Matlab的自动泊车系统开发:利用模糊控制实现智能停车解决方案的详细教程

Matlab是一种广泛应用于科学计算、工程建模与仿真的编程语言,其强大的工具箱和简洁的编程语法,使其成为开发自动泊车系统的理想选择。在开始编写代码之前,我们需要搭建Matlab的工作环境,并熟悉相关的工具箱,如Fuzzy Logic Toolbox,用于实现模糊控制。首先,确保你已经安装了Matlab软件,并加载了必要的工具箱。接下来,我们将逐步讲解如何在Matlab中实现自动泊车系统。

qq_38334677的博客 663

使用JPype实现Python调用JAVA程序

BTCC给的程序化交易例子是用的Java语言的Fix金融交换协议,QuickFix的C++代码和python调用quickfix库在建立连接时有一些问题没有弄明白,以后有时间了再看,现在只能先使用BTCC给的java代码来获取专业交易的市场数据以及使用这个Java代码来进行交易下单。无奈之下找到了一个python调用Java程序的库Jpype。这里转载收藏一下。之所以要用python,是因为pyt

Mage的专栏 3988

华为OD新系统机试真题 - 端口流量统计

华为OD机试新系统真题【端口流量统计】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统4月26号机试真题【端口流量统计】。

qq_45776114的博客 762

Java中package(包)的总结(一)

概述        Java程序是基于Class,随着Java类越写越多,难免会出现类重名的现象。为了在使用它们的时候不让编译器混淆,我们给类加上一个限定(前缀),即把它们放在不同的包里面,调用时再加上前缀。比如,A班有一个张三,B班也有一个张三,我们要让A班张三做某事时,就把它们分别放到A、B包中,然后调用A.张三即可。这样好处是对同名的类进行了区分;能精确指出我们需要的哪一个;让同名的类在一...

小景的博客 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

JNI 资源释放

JNI 编程实现了 native code 和 Java 程序的交互,因此 JNI 代码编程既遵循 native code 编程语言的编程规则,同时也遵守 JNI 编程的文档规范。在内存管理方面,native code 编程语言本身的内存管理机制依然要遵循,同时也要考虑 JNI 编程的内存管理。 本章简单概括 JNI 编程中显而易见的内存泄漏。从 native code 编程语言自身的内存管理,

进击吧!! 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java中不带package和带package的编译运行方式

java中不带package的程序和带package的程序编译的方式是不同的。 一、不带package的程序 建立个HelloWorld.java的文件,放入C:\,内容如下: public class HelloWorld {    public static void main(String args[])    //向屏幕上写字符串"HelloWorld!"     {

姚老板的黑店 1945

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

CodeModel生成Java类

CodeModel的使用示例

橡果生长记的博客 3177

一文带你彻底搞懂Java和JavaScript的区别与相似之处(纯干货建议收藏)

随着时间的推移,软件编程世界发展迅速,并提供了许多编程语言。您可能听说过 Java 和 JavaScript 的编程语言,名称听起来相似,并且可能对它们是同一种语言的不同名称还是不同感到困惑。在这个保姆级别且充满干货的文章之后,我相信你所有的困惑都会烟消云散。...

努力是为了站在万人之中,成为别人的光 7万+

java中package(包)的使用理解

最近在学习java,在学习到对象和类这一部分时,接触了java中很重要的一个概念:package,也就是包。一开始对于package的使用我产生了许多疑惑,不仅是理论上的,在实际写代码的尝试中也出现了许多意想不到的错误。之后自己查阅了许多博客以及stackoverflow上的一些讲解,再结合编写代码试验,总算是稍微弄清楚了关于package的使用,在此为自己的理解做一个笔记。 package的简...

立志变成java巨头 8939

Java中package的作用及import 导入的用法

package的作用 1:为了解决类之间的重名问题。 2:为了便于管理类:合适的类位于合适的包! MVC 分层开发 dao:数据访问层 抽象层 dao.impl:数据访问层的实现包 servlet:控制层 service:业务层 抽象层 service.impl:业务层的的实现包 util:工具包 entity:实体包 filter:过滤器包 包通常是类的第一句非注释性语句。 一个类治只有一个...

fengbingbing1的博客 9391

12.6 包的声明和访问

包的概念:java的包,其实就是我们电脑系统中的文件夹,包里存放的是类文件。当类文件很多的时候,通常我们会采用多个包进行存放管理他们,这种方式称为分包管理。在项目中,我们将相同功能的类放到一个包中,方便管理。并且日常项目的分工也是以包作为边界。类中声明的包必须与实际class文件所在的文件夹情况相一致,即类声明在a包下,则生成的.class文件必须在a文件夹下,否则,程序运行时会找不到类。包的声明...

southdreams的博客 505
上一篇: [原创]类似Java语法的Javascript框架js5(v2)
下一篇: Javascript写的Java --- j语言
staffrobot
博客等级 码龄19年 6粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值