为什么这个javascript对象引用了前一个对象的属性?

时间:2013-04-30 18:12:18

标签: javascript jquery class object

我正在创建一个可以在页面上创建任意数量的验证码的类。我有一个captcha类,我用它来实例化新的验证码对象c1c2。这是我的JS:

 $(function(){
    var captcha = {
        parentForm : '',
        container : '',
        captcha_input : '',
        number1 : 0,
        number2 : 0,

        createCaptcha : function(form_ID){
            var newHtml;
            this.parentForm = $('#' + form_ID);
            this.container = this.parentForm.find('.captchaContainer');
            this.number1 = this.randomNumber(10);
            this.number2 = this.randomNumber(10);


            newHtml = 'What does ' + this.number1 + ' plus ' + this.number2 + ' equal? <b class="required goldenrod" title="Required Field">*</b><br/><br/><input type="text" name="captcha">';
            this.container.html(newHtml);
        },

        isValid : function(){
            console.log(this.container);
            this.captcha_input = this.container.find('input[name="captcha"]');
            if (this.number1 + this.number2 == this.captcha_input.val()) {
                this.captcha_input.css('background-color', '')
                return true;
            } else{
                this.captcha_input.css('background-color', '#FFCCCC')
                alert(this.number1 + ' plus ' + this.number2 + ' does not equal ' + this.captcha_input.val() + '. Please try again.');
                this.captcha_input.focus();
                return false;
            }
        },

        randomNumber : function(max){ return Math.floor(Math.random()*(max+1)); }
    }


    var c1 = captcha,
        c2 = captcha;

    c1.createCaptcha("form1");
    c2.createCaptcha("form2");

    $('#form1 input[type="submit"]').click(function() { 
        if(c1.isValid()){
            alert('Captcha is valid!');
        }else{
            return false;
        }
    });
    $('#form2 input[type="submit"]').click(function() { 
        if(c2.isValid()){
            alert('Captcha is valid!');
        }else{
            return false;
        }
    });


});

我的HTML:

<form id="form1">
    <div class="captchaContainer"></div>
    <input type="submit">
</form>
<form id="form2">
    <div class="captchaContainer"></div>
    <input type="submit">
</form>

当我点击form1的提交按钮时,似乎isValid方法正在为c2而不是c1运行,就像我期望的那样。知道为什么会这样做吗?

有几点需要注意:

  • 如果我添加了更多captcha个实例和HTML,则每个提交按钮都会在点击的isValid的最后一个实例上运行captcha
  • 这需要适用于IE8 +

以下是代码的fiddle

非常感谢任何帮助。谢谢!

3 个答案:

答案 0 :(得分:1)

c1c2都是同一个对象。使用Object.create创建不同的实例。旧浏览器不支持Object.create,但我提供的链接中有一个填充。

var c1 = Object.create(captcha),
    c2 = Object.create(captcha);

答案 1 :(得分:1)

您还可以执行该对象的深层复制。

 function deepCopy(obj) { 
     var res = {};
     for (var key in obj) {
         if (obj.hasOwnProperty(key)) {
             res[key] = obj[key];
         };
     }
     res.prototype = obj.prototype; // this would make it a deep copy.
     return res;
};
var c1 = deepCopy(captcha);

答案 2 :(得分:0)

虽然@plalx有一个有效的答案,但它不是我的方案的理想答案。因为我不能实例化一个从对象文字创建的类(不使用Object.create),所以我决定用函数重构我的类:

$(function(){
    var Captcha = function(){
        var parentForm = '',
            container = '',
            captcha_input = '',
            number1 = 0,
            number2 = 0,

            createCaptcha = function(form_ID){
                var newHtml;
                this.parentForm = $('#' + form_ID);
                this.container = this.parentForm.find('.captchaContainer');
                this.number1 = randomNumber(10);
                this.number2 = randomNumber(10);


                newHtml = 'What does ' + this.number1 + ' plus ' + this.number2 + ' equal? <b class="required goldenrod" title="Required Field">*</b><br/><br/><input type="text" name="captcha">';
                this.container.html(newHtml);
            },

            isValid = function(){
                this.captcha_input = this.container.find('input[name="captcha"]');
                if (this.number1 + this.number2 == this.captcha_input.val()) {
                    this.captcha_input.css('background-color', '')
                    return true;
                } else{
                    this.captcha_input.css('background-color', '#FFCCCC')
                    alert(this.number1 + ' plus ' + this.number2 + ' does not equal ' + this.captcha_input.val() + '. Please try again.');
                    this.captcha_input.focus();
                    return false;
                }
            },

            randomNumber = function(max){ return Math.floor(Math.random()*(max+1)); }

            return{
                createCaptcha : createCaptcha,
                isValid : isValid
            }
    }


    // Instantiation of Captcha objects
    var c1 = new Captcha,
        c2 = new Captcha;

    c1.createCaptcha("form1");
    c2.createCaptcha("form2");

    $('#form1 input[type="submit"]').click(function() { if(c1.isValid()){ alert('Captcha is valid!'); }else{ return false; } });
    $('#form2 input[type="submit"]').click(function() { if(c2.isValid()){ alert('Captcha is valid!'); }else{ return false; } });

});

以下是新工作fiddle

TLDR:由于在没有Object.create的情况下无法实例化对象文字,我使用了一个函数来创建类,然后像这样实例化:

var c1 = new Captcha,
    c2 = new Captcha;