请大神帮我解答一下这个函数。。。包括function中的两个参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请大神帮我解答一下这个函数。。。包括function中的两个参数相关的知识,希望对你有一定的参考价值。

详细一点,,麻烦您了。
$.SwatchBook = function( options, element )
this.$el = $( element );
this._init( options );

我下载的插件中调用方法$('#sb-container').swatchbook(对原型插件中默认参数进行修改的参数),这个是不是也可以写成这样呢?
$.SwatchBook (#sb-container,需要修改的参数),请您认真看一下我的问题,我只是想知道这个方法为什么这么写,这么写有什么具体作用,又是如何调用这个函数仅此而已

参考技术A


jQuery插件开发的五种形态

    插件的第一形态

面对这种情况,通常我们会通过定义function的方式来实现。


复制代码代码如下:


function pluginName($selector)
    $.each($selector, function ()
        $(this).css("background-color", "#ccc");
        // to do something...
    );

// pluginName(document.getElementsByClassName("demo"));


因为我谈的是jQuery插件开发,那么我现在把这段代码扩展到jQuery上,代码如下:


复制代码代码如下:


// IIFE(立即调用函数表达式);  [参考 http://suqing.iteye.com/blog/1981591/]
;(function ($)
    // 扩展这个方法到jQuery.
    // $.extend() 是吧方法扩展到 $ 对象上,和 $.fn.extend 不同。 扩展到 $.fn.xxx 上后,
    // 调用的时候就可以是 $(selector).xxx()
    $.fn.extend(
        // 插件名字
        pluginName: function ()
            // 遍历匹配元素的集合
            // 注意这里有个"return",作用是把处理后的对象返回,实现链式操作
            return this.each(function ()
                // 在这里编写相应的代码进行处理
            );
       
    );
// 传递jQuery到内层作用域去, 如果window,document用的多的话, 也可以在这里传进去.
// )(jQuery, window, document, undefined);
)(jQuery, undefined);
// 调用方式 $(".selector").pluginName().otherMethod();


但是还差的远,目前只解决了两个问题

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

    插件的第二形态

现在来给插件添加参数支持。代码如下


复制代码代码如下:


;(function($)
    $.fn.pluginName = function(options)
        // 合并参数,通过“extend”合并默认参数和自定义参数
        var args = $.extend(, $.fn.pluginName.defaults, options);
        return this.each(function()
            console.log(args.text);
            // to do something...
        );
    ;
    // 默认参数
    $.fn.pluginName.defaults =
        text : "hello"
    ;
)(jQuery);
// $(".selector").pluginName(
//     text : "hello world!"
// );


添加参数支持还比较容易些,又解决一问题

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

    插件的第三形态

现在来添加方法的支持,我前面所提到的生命周期可控制,意思差不多,例如添加reInit,destory等方法来控制插件。


复制代码代码如下:


;(function($)
    $.fn.pluginName = function (method)
        // 如果第一个参数是字符串, 就查找是否存在该方法, 找到就调用; 如果是object对象, 就调用init方法;.
        if (methods[method])
            // 如果存在该方法就调用该方法
            // apply 是吧 obj.method(arg1, arg2, arg3) 转换成 method(obj, [arg1, arg2, arg3]) 的过程.
            // Array.prototype.slice.call(arguments, 1) 是把方法的参数转换成数组.
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        else if (typeof method === 'object' || !method)
            // 如果传进来的参数是"...", 就认为是初始化操作.
            return methods.init.apply(this, arguments);
        else
            $.error('Method ' + method + ' does not exist on jQuery.pluginName');
       
    ;
    // 不把方法扩展在 $.fn.pluginName 上. 在闭包内建个"methods"来保存方法, 类似共有方法.
    var methods =
        /**
         * 初始化方法
         * @param _options
         * @return *
         */
        init : function (_options)
            return this.each(function ()
                var $this = $(this);
                var args = $.extend(, $.fn.pluginName.defaults, _options);
                // ...
            )
        ,
        publicMethod : function()
            private_methods.demoMethod();
       
    ;
    // 私有方法
    function private_methods =
        demoMethod : function()
   
    // 默认参数
    $.fn.pluginName.defaults =
    ;
)(jQuery);
// 调用方式
// $("div").pluginName(...);  // 初始化
// $("div").pluginName("publicMethod");  // 调用方法


又解决一问题

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

    插件的第四形态

第三形态的插件修改就已经可以应对大多数插件的需求了。精益求精嘛,继续升级。
第四形态的插件是照帮司徒正美的《javascript框架设计》的代码。加了点面向对象的知识。


复制代码代码如下:


(function ($)
    var Plugin = function (element, options)
        this.element = element;
        this.options = options;
    ;
    Plugin.prototype =
        create: function ()
            console.log(this.element);
            console.log(this.options);
       
    ;
    $.fn.pluginName = function (options)
        // 合并参数
        return this.each(function ()
            // 在这里编写相应的代码进行处理
            var ui = $._data(this, "pluginName");
            // 如果该元素没有初始化过(可能是新添加的元素), 就初始化它.
            if (!ui)
                var opts = $.extend(true, , $.fn.pluginName.defaults, typeof options === "object" ? options : );
                ui = new Plugin(this, opts);
                // 缓存插件
                $._data(this, "pluginName", ui);
           
            // 调用方法
            if (typeof options === "string" && typeof ui[options] == "function")
                // 执行插件的方法
                ui[options].apply(ui, args);
           
        );
    ;
    $.fn.pluginName.defaults = ;
)(jQuery);
// 调用的方式和之前一样。


这里特别要提下缓存这个东西,插件用多了,觉的这个真的是好东西。
在传统面向对象的插件开发中,至少会声明个变量保存它,但是我到目前写的jQuery插件中都没有,用起来很麻烦。自从把初始化后的插件缓存起来后,方便了许多。通过代码$("#target").data("pluginName")就可以取到对象了。 来看看还有什么问题没有解决

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

    插件的第五形态

看了上面的代码是否脑子有点晕了,如果是,休息片刻,稍后回来,下面的代码更精彩。 最后一个方案算是比较全面的了。方案来自Bootstrap,下面代码以 Bootstrap 的 button 插件为例.


复制代码代码如下:


!function ($)
    // ecma262v5 的新东西, 强制使用严谨的代码编写.
    "use strict";
    // BUTTON PUBLIC CLASS DEFINITION
    // ==============================
    var Button = function (element, options)
        this.$element = $(element);
        this.options = $.extend(, Button.DEFAULTS, options);
    ;
    Button.DEFAULTS =
        loadingText: 'loading...'
    ;
    Button.prototype.setState = function (state)
        // ...
    ;
    Button.prototype.toggle = function ()
        // ...
    ;
    // BUTTON PLUGIN DEFINITION
    // ========================
    var old = $.fn.button; // 这里的 $.fn.button 有可能是之前已经有定义过的插件,在这里做无冲突处理使用。
    $.fn.button = function (option)
        return this.each(function ()
            var $this = $(this);
            // 判断是否初始化过的依据
            var data = $this.data('bs.button');
            var options = typeof option == 'object' && option;
            // 如果没有初始化过, 就初始化它
            if (!data) $this.data('bs.button', (data = new Button(this, options)));
            if (option == 'toggle') data.toggle();
            else if (option) data.setState(option)
        )
    ;
    // ① 暴露类名, 可以通过这个为插件做自定义扩展
    $.fn.button.Constructor = Button;
    // 扩展的方式
    // 设置 : $.fn.button.Constructor.newMethod = function()
    // 使用 : $btn.button("newMethod");
    // ② 无冲突处理
    $.fn.button.noConflict = function ()
        $.fn.button = old;
        return this
    ;
    // ③ 事件代理, 智能初始化
    $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e)
        var $btn = $(e.target);
        // 查找要初始化的对象
        if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn');
        // 直接调用方法, 如果没有初始化, 内部会先进行初始化
        $btn.button('toggle');
        e.preventDefault();
    );
(jQuery);


来看看还有什么问题没有解决

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

补充

现在的插件都要求灵活性要高,比如希望插件可以同时适配jQuery和Zepto,又或者需要支持AMD或者CMD规范。

支持jQuery和Zepto


复制代码代码如下:


if (window.jQuery || window.Zepto)
  (function ($)
      // plugin code...
  )(window.jQuery || window.Zepto);


中间件支持,node


复制代码代码如下:


if (typeof(module) !== 'undefined')

  module.exports = pluginName;

requirejs(AMD) support
if (typeof define === 'function' && define.amd)
  define([], function ()
      'use strict';
      return pluginName;
  );

seajs(CMD) support
if (typeof define === 'function')
  define([], function ()
      'use strict';
      return pluginName;
  );

追问

大哥虽然挺多挺全面的笔记,但是有点答非所问。我用的插件对应你笔记中的第五个方法
$.SwatchBook = function( options, element )
this.$el = $( element );
this._init( options );
;
这个方法也不一样啊。我这不是定义新名字,这个$.SwatchBook是意思是对这个SwatchBook的方法进行扩展吗?

c#中tcp异步编程遇到异常问题,新手感觉很不得懂 希望大神能从浅显的角度帮我解答

//发起连接请求
private void ConnectoServer()

AsyncCallback requestcallback = new AsyncCallback(RequestCallBack);
statusStripInfo.Invoke(shwStatusInfoCallBack, "正在连接...");
statusStripInfo.Invoke(shwProgressProcCallBack, 1);
//tcpClient = new TcpClient(AddressFamily.InterNetwork);//获得本机的ip地址
tcpClient = new TcpClient(host,52888);
//tcpClient = new Socket(AddressFamily.InterNetwork,);
IAsyncResult result = tcpClient.BeginConnect(IPAddress.Parse(tbxSrvIp.Text), int.Parse(tbxPort.Text), requestcallback, tcpClient); //异步操作1
注:host是在之前定义过的一个ip地址
这个一个客户端的部分代码,源代码本来是:
//tcpClient = new TcpClient(AddressFamily.InterNetwork);//获得本机的ip地址。
运行时没有错误,但是我不想这里指定本机ip,我想指定一个固定的服务器ip,所以讲其注释掉改成:
tcpClient = new TcpClient(host,52888);host为我指定的ip
编译时候没有错误,在窗口中点击连接时,就出现异常

其实tcp编程还不是很会,希望好心人能帮我解答。

注:host是在之前定义过的一个ip地址
这个一个客户端的部分代码,源代码本来是:
//tcpClient = new TcpClient(AddressFamily.InterNetwork);//获得本机的ip地址。
运行时没有错误,但是我不想这里指定本机ip,我想指定一个固定的服务器ip,所以讲其注释掉改成:
tcpClient = new TcpClient(host,52888);host为我指定的ip
上面是你理解的有问题。
第一:tcpClient = new TcpClient(AddressFamily.InterNetwork);这句话不是获得本机的ip地址,而是要创建一个使用ip版本4的寻址方案的TcpClient对象。这时只是定义这个对象,并没有建立连接
第二:tcpClient = new TcpClient(host,52888);这句代码的意思是建立一个连接到host和其端口52888的连接,在创建时就已经连接上了。这里的host指的是你要连接的服务器IP地址。此时在创建时已经建立连接了,所以在使用BeginConnect异步调用时,抛出一个【在一个已经建立连接的套接字上做一个连接请求。

你理解上面的内容,应该就可以解决你的问题了。追问

非常感谢你对我的回答,才开始学c#确实搞不定。那原来程序是tcpClient = new TcpClient(AddressFamily.InterNetwork)这句只是定义了对象 并没有实例化,那在使用异步操作 IAsyncResult result = tcpClient.BeginConnect(IPAddress.Parse(tbxSrvIp.Text), int.Parse(tbxPort.Text), requestcallback, tcpClient);时 是如何找到ip的呢??我又想了想 我是不是应该在(IPAddress.Parse(tbxSrvIp.Text)这个参数中去得到ip地址呢??

追答

那在使用异步操作 IAsyncResult result = tcpClient.BeginConnect(IPAddress.Parse(tbxSrvIp.Text), int.Parse(tbxPort.Text), requestcallback, tcpClient);时 是如何找到ip的呢??我又想了想 我是不是应该在(IPAddress.Parse(tbxSrvIp.Text)这个参数中去得到ip地址呢??

BeginConnect方法,在此时有四个参数,第一个就是服务器的IP地址,第二个是服务器的端口。
tbxSrvIp.Text应该是是服务器IP地址,tbxProt.Text就是服务器端口。
你想得到什么ip地址?是你本机的IP地址还是服务器的IP地址?

参考技术A 你这样写呢 TcpCilent tcpClient= new TcpClient();
client.Connect("localhost",52888);不行再问。 如果想改成别的IP地址则把localhost改成对应的“127.0.0.1”格式 的IP地址,记得带双引号。追问

不知道 这样改了要出错

参考技术B ( n u l l )

以上是关于请大神帮我解答一下这个函数。。。包括function中的两个参数的主要内容,如果未能解决你的问题,请参考以下文章

这个toString()语句和return语句如何用??求解答:给位大神说一下toString的用法,重点

各位大神速度帮我解答下好么,谢谢了,在线等,C++

我在做一个MATLAB仿真模糊PID,规则,系统图都已经完成就是怎么都运行不成功,请大神帮我看一下可以吗?

来个大神帮我解释一下这个语句STM32F4,这个置位RCC_AHB1ENR = (1<<5)?

请高手解答在windows7中的为此网络启用联邦信息处理标准(FIPS)兼容究竟是啥意思大神们帮帮忙

MySQL触发器语句,那个地方出错了吗,请大神解答一下