function s(){};
s.prototype={
_cols:[],
drawTitle:function(titles){
var me=this;
titles=titles||[];
var c={name:'',width:10,type:'multi'};
titles.splice(0,0,c);//向titles数组在0位置上插入一个对象
for(var j=0;j<titles.length;j++){
this._cols[j]=titles[j];
}
}
}var a=new s();
alert(s.prototype._cols.length)//原型的属性不会因实例中的属性变化而变化吧?
a.drawTitle([1,2,3]);
alert(s.prototype._cols.length)//但它确实变了!以上代码怎么把原型中的_cols属性变掉了呢?感觉是splice函数可能对数组的引用产生的问题,但是不明白为什么?

解决方案 »

  1.   

    这样不会变!
    function s()
        {
        }
        s.prototype = {
            _cols: [],
            init:function(_cols)
            {
                this._cols=_cols;
            },
            drawTitle: function(titles)
            {
                var me = this;
                titles = titles || [];
                var c = { name: '', width: 10, type: 'multi' };
                titles.splice(0, 0, c); //向titles数组在0位置上插入一个对象
                for (var j = 0; j < titles.length; j++)
                {
                    this._cols[j] = titles[j];
                }
            }
        }    var a = new s();
        a.init([]);
        alert(s.prototype._cols.length)//原型的属性不会因实例中的属性变化而变化吧?
        a.drawTitle([1, 2, 3]);
        alert(s.prototype._cols.length)//这个不变
        alert(a._cols.length); //这个变
      

  2.   

    但问题是为什么会变呢
    我觉得是splice的问题,但是splice有什么特殊的呢?每个实例的属性应该互不影响才是。
      

  3.   

    titles.splice(0,0,c);//向titles数组在0位置上插入一个对象
    to:
    titles.unshift(c);//向titles数组在0位置上插入一个对象
      

  4.   

    好像不是splice的问题,改成unshift或者push也不行,
      

  5.   


    function s(){};
    s.prototype={
    _cols:[],
    drawTitle:function(titles){
    for(var j=0;j<titles.length;j++){
    this._cols[j]=titles[j];
    }
    }
    }var a=new s();
    alert(s.prototype._cols.length)
    a.drawTitle([1,2,3]);
    alert(s.prototype._cols.length)
    是数组对象的特殊吗?怎么会影响到原型的属性呢
      

  6.   

    原型的属性是不变,而且所有实例共享。当new一个实例a出来的时候,你访问实例的a._cols属性,可是它并不存在,所以顺着原型链向上找,找到了s.prototype._cols。这个时候就体现了原型属性的共享。当你给a._cols赋值时,因为a._cols并不存在,所以就创建了一个a._cols属性并给它赋值,你以后再访问a._cols时,就是访问的实例a的_cols属性,此时就体现了原型属性的不变。而LZ的代码可以说是种特殊情况。你赋值的时候,是给a._cols[j]赋值,而不是a._cols。所以如果要完成这次赋值,按道理是分两步的:首先创建一个a._cols = [];然后是添加一个成员并赋值 a._cols[j] = xxxx;可是电脑没那么聪明,因此就直接找到己有的能够访问的s.prototype._cols并给它添加了一个成员并赋值;LZ的赋值方式:function s(){};
    s.prototype={
        _cols:[],
        drawTitle:function(titles){
            var me=this;
            titles=titles||[];
            var c={name:'',width:10,type:'multi'};
            titles.splice(0,0,c);//向titles数组在0位置上插入一个对象
            for(var j=0;j<titles.length;j++){ //循环赋值
                this._cols[j]=titles[j];
            }
        }
    }var a=new s();
    a.drawTitle([1,2,3]);
    alert(a._cols);
    alert(s.prototype._cols)
    delete a._cols; //揭示关键之所在
    alert(a._cols);
    alert(s.prototype._cols);
    直接赋值方式:function s(){};
    s.prototype={
        _cols:[],
        drawTitle:function(titles){
            var me=this;
            titles=titles||[];
            var c={name:'',width:10,type:'multi'};
            titles.splice(0,0,c);//向titles数组在0位置上插入一个对象
    this._cols=titles; //直接赋值
        }
    }var a=new s();
    a.drawTitle([1,2,3]);
    alert(a._cols);
    alert(s.prototype._cols)
    delete a._cols;  //揭示关键之所在
    alert(a._cols);
    alert(s.prototype._cols);
    大家分别运行一下上面的两段代码就明白了