【问题标题】:Can't call Javascript object method无法调用 Javascript 对象方法
【发布时间】:2014-02-09 19:12:54
【问题描述】:

我在加载页面时收到控制台错误TypeError: bodys.show is not a function。我做错了什么?

function loadingScreen(selector,css)
{
    this.loadingAnimation = $("<div><p>Loading</p><div></div></div>").appendTo(selector);
    this.containerCss = $.extend({'border-radius':"20px",position:"absolute",height:"40px",width:"120px","display":"none"}, css);
    this.loadingAnimation.css(this.containerCss);
    this.p = this.loadingAnimation.children("p").first();
    this.p.css({width:"100%",'text-align':"center"});
    this.div = this.loadingAnimation.children("div").first();
    this.div.css({position:"abslolute",left:"0",top:"0",'background-color':"rgba(255,100,100,0.5)",height:"100%",width:"10%"});
    function show(){
        this.loadingAnimation.css("display","block");
        animate(this.div,"right");
    }
    function hide(){
        this.loadingAnimation.css("display","none");
        this.div.stop(true,true);
        this.div.css("margin-left","0px");
    }
    function animate(element,direction)
    {
        if(direction === "right"){
            element.animate({"margin-left":"120px"},animate(element,"left"));
        }
        else if(direction === "left"){
            element.animate({"margin-left":"0px"},animate(element,"right"));
        }
    }
}

$(document).ready(function()
{
    var bodys = new loadingScreen("body",{});
    bodys.show();
});

【问题讨论】:

    标签: javascript object methods


    【解决方案1】:

    在函数体内声明变量/函数时,它们是“私有的”,除非它们作为函数本身的属性附加 - 在函数体内,您可以使用 this 关键字来执行此操作。

    函数show()在loadingScreen中是私有的,为了让它作为其父函数的成员被访问,用this声明它:

    this.show  = function(){...
    
    ...}
    

    ...它仍然可以访问loadingScreen 范围内的所有内容,但可以作为loadingScreen 的方法在外部调用。

    编辑:

    正如 Naomik 在下面指出的,你也可以将它附加到对象的原型上:

    loadingScreen.prototype.show = function()...
    

    ...显然原型函数比标准成员声明执行得更快,但是 - 因为您将在主函数体之外声明它,所以它无法访问函数内部的私有变量,所以在这种情况下用处不大。

    【讨论】:

    • 如何将参数传递给函数? this.show = function(param1,param2){} 之类的东西?
    • 是的,和普通函数完全一样,你所做的只是改变声明,function关键字后面的括号应该包含你希望传递的任何参数。
    【解决方案2】:

    目前show()函数定义在loadingScreen的本地/私有范围内,为了使show公开可见使用this.show

    所以把你的代码改成

     this.show = function() {
    

    而不是

    function show(){
    

    【讨论】:

      【解决方案3】:

      您可以在构造函数中使用this.show = show;show 附加到新实例

      或者你可以这样做

      // loading-screen.js
      (function(window, $) {
      
        var LoadingScreen = function (selector, css) {
          this.$elem = $(selector);
          this.$elem.css(css);
        };
      
        LoadingScreen.prototype.show = function () {
          return this.$elem.show();
        };
      
        LoadingScreen.prototype.hide = function () {
          return this.$elem.hide();
        };
      
        window.LoadingScreen = LoadingScreen;
      
      })(window, jQuery);
      

      作为原型的一部分,showhide 函数现在可以被LoadingScreen 的任何实例访问。最重要的是,您有一个不错的小代码模块,可以与所有其他脚本分开包含。

      用法

      <script src="loading-screen.js"></script>
      <script>
        $(function() {
          var ls = new LoadingScreen("body", {});
          ls.show();
          ls.hide();
        });
      </script>
      

      jQuery 插件a demo

      由于您无论如何都在使用 jQuery,而不是将 selector 和一些 css 传递给 vanilla 构造函数,将其包装在 jQuery 插件中可能是有意义的。

      (function(window, $) {
      
        var LoadingScreen = function($elems, css) {
          this.$elems = $elems;
          this.$elems.css(css);
        };
      
        LoadingScreen.prototype.show = function() {
          this.$elems.slideDown(250);
        };
      
        LoadingScreen.prototype.hide = function() {
          this.$elems.slideUp(250);
        };
      
        $.fn.loadingScreen = function(css) {
          return new LoadingScreen(this, css);
        };
      
      })(window, jQuery);
      

      用法非常相似,但看起来更像传统的 jQuery

      $(function() {
        var ls = $("p").loadingScreen({backgroundColor: "blue"});
      
        // notice .show and .hide delegate to our plugin methods now
        ls.show();
      });
      

      【讨论】:

      • @MickMalone1983,我也不知道。有些人就是不知道。没关系。
      猜你喜欢
      • 2012-06-24
      • 2016-04-13
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多