为什么这个javascript对象引用的是以前的对象';谁的财产?

为什么这个javascript对象引用的是以前的对象';谁的财产?,javascript,jquery,class,object,Javascript,Jquery,Class,Object,我正在创建一个类,该类可以在页面上创建任意数量的验证码。我有一个captcha类,用于实例化新的验证码对象c1和c2。这是我的JS: $(function(){ var captcha = { parentForm : '', container : '', captcha_input : '', number1 : 0, number2 : 0, createCaptcha : func

我正在创建一个类,该类可以在页面上创建任意数量的验证码。我有一个
captcha
类,用于实例化新的验证码对象
c1
c2
。这是我的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;
        }
    });


});
$(函数(){
var验证码={
父窗体:“”,
容器:“”,
验证码输入:“”,
数字1:0,
数字二:0,,
createCaptcha:函数(表单ID){
var-newHtml;
this.parentForm=$(“#”+表单ID);
this.container=this.parentForm.find('.captchaContainer');
this.number1=this.randomNumber(10);
this.number2=this.randomNumber(10);
newHtml='什么是'+this.number1+'加'+this.number2+'等于?*

'; this.container.html(newHtml); }, isValid:function(){ console.log(this.container); this.captcha_input=this.container.find('input[name=“captcha”]”); 如果(this.number1+this.number2==this.captcha_input.val()){ 这个.captcha_input.css('background-color','') 返回true; }否则{ 这个.captcha_input.css('background-color','FFCCCC')) 警报(this.number1+'加上'+this.number2+'不等于'+this.captcha_input.val()+'。请重试'); 这个.captcha_input.focus(); 返回false; } }, 随机数:函数(max){return Math.floor(Math.random()*(max+1));} } var c1=验证码, c2=验证码; c1.createCaptcha(“格式1”); c2.createCaptcha(“格式2”); $(#form1 input[type=“submit”]”)。单击(function(){ if(c1.isValid()){ 警报(“验证码有效!”); }否则{ 返回false; } }); $(#form2 input[type=“submit”]”)。单击(function(){ if(c2.isValid()){ 警报(“验证码有效!”); }否则{ 返回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,则单击
    captcha
    的最后一个实例时,每个提交按钮都将运行
    isValid
  • 这需要对IE8起作用+
下面是一段正在运行的代码


任何帮助都将不胜感激。谢谢

c1
c2
都是同一个对象。用于创建不同的实例
Object.create
在旧浏览器中不受支持,但是我提供的链接中有一个polyfill

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

虽然@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; } });

});

还可以执行对象的深度复制

 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);

c1和c2都是对同一
captcha
对象的引用。@RickViscomi同意,因为代码状态为var c1=captcha,c2=captcha;c1和c2都是指向captcha对象的指针,因此它们都是同一个对象。这会导致对1个对象c1的更改影响c2和CATCH对象。啊,这一切都是有意义的。谢谢我想我的印象是,定义这些变量将生成一个实例而不是指针。你们中的任何一个能告诉我为什么存储在变量中的对象是这样的,而不是存储在变量中的数字这样的东西吗<代码>变量myNumber=1,myNewNumber=myNumbervs
var myObject={prop1:'red'},myNewObject=myObject
@Fillip:它对所有数据类型都适用!区别在于,对于对象,变量的值是对对象的引用,而不是对象本身。而且,对象是可变的,而数字是不可变的。@FelixKling-谢谢你的解释!有道理!看来这会对我有用的。我想我只是误解了如何实例化由对象文本生成的类。在我接受此答案之前,您是否知道
对象是否存在跨浏览器问题。创建
?@FillipPeyton是的,用于支持不兼容的浏览器。@bfavaretto-谢谢。虽然这个polyfill可以解决我的问题,但当我可以将类重新构造为从函数而不是对象文本创建时,我不一定要添加更多代码。如果你想提交一个建议使用函数的答案,我很乐意接受这个答案。谢谢@FillipPeyton谢谢,但我可能不会再添加其他答案了。如果您决定重新考虑,polyfill非常简单,Object.create是当前语言标准的一部分(只是IE8及以下版本的旧浏览器不支持它)。@bfavaretto-这很公平。谢谢你的帮助!有趣。我从来不知道。谢谢@alex23
var c1=$.extend({},captcha)
等也可以。有趣。这也是一个不错的解决方案,
 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);