Home  >  Q&A  >  body text

JavaScript这样写的好处是什么?


function Rectangle(w,h){ this.width=w; this.height=h; this.area=function () { return this.width*this.height; } } function Rectangle1(w,h){ this.width=w; this.height=h; Rectangle1.prototype.area=function () { return this.width*this.height; } } var a= new Rectangle(3,4); alert(a.area());

使用原型有哪些好处呢?节省内存?我感觉第一种方法定义类就够用了啊!!
求大神解惑传道

怪我咯怪我咯2749 days ago553

reply all(8)I'll reply

  • PHPz

    PHPz2017-04-10 14:45:48

    @魔尼尼ongogoda点com 把这段代码复制到chrome的控制台中运行下看看:

    function Rectangle1(w,h){
        var $width=w,
            $height=h;
    
        //每实例化一个对象都会重写prototype中的area,
        //个人认为这样写有问题,除非有理由要这么写
        Rectangle1.prototype.area=function  ()  {
            return   $width*$height;
        }
    }
    
    var r1 = new Rectangle1(1, 2);
    console.log(r1.area()); //输出2
    
    var r2 = new Rectangle1(3, 4);
    console.log(r1.area(), r2.area());//输出12,12
    

    我不知道这样写是有意为之,还是一个失误,如果要模拟私有变量可以这样写:

    function Rectangle(w, h) {
      var width = w;
      var height = h;
    
      this.area = function () {
        return width * height;
      };
    }
    

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 14:45:48

    不同的定义方法而已.. 具体请参考:http://segmentfault.com/blog/stephenlee/1190000000478987


    更新...的确是不一样的.. 看图即可明白

    reply
    0
  • 黄舟

    黄舟2017-04-10 14:45:48

    考虑了下,还是把答案删除比较好,免得起误导作用,之前的代码实验性太强,没有什么可操作性。

    第一段代码是正确,而第二段代码是错误的。至于为什么 KevinYue 已经给了解答,原型的好处之一是可以共用函数,因为当你访问某个ins实例上没有的方法而恰好proto上有的话,函数会以ins -> proto -> func的顺序访问,来返回你需要的结果。

    而通常,我们都是这样定义prototype的,也就是放在外面定义。

    function fn(){ }
    fn.prototype.method=function(){/* code */}
    

    reply
    0
  • 黄舟

    黄舟2017-04-10 14:45:48

    个人感觉第二种写法有问题。
    应该是像下面这样的吧?

    function   Rectangle1(w,h){
         this.width=w;
         this.height=h;
    }
    Rectangle1.prototype.area=function  ()  {
         return   this.width*this.height;
    }
    

    至于为什么要这样,是因为像有些时候需要的实例没有必要用到area这个方法,所以就不用把他放到构造函数中,这样就不会再new实例的时候都会在每个实例内带有area这个方法,节省资源,对性能有好处。放到原型上,就可以在需要用到该方法的时候再去查找原型,就能使用该方法。

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 14:45:48

     var Rectangle = function() {
        function Rectangle(w, h) {
            this.width  = w;
            this.height = h;
        }
    
        Rectangle.prototype.area = function() {
            return this.width * this.height;
        }
    
        return Rectangle;
    }();
    

    我喜歡寫成這樣。理由:
    1. 性能與標準實現基本無異;
    2. 使用閉包與導出的形式,方便在不破壞公共作用域的前提之下擴展;
    3. 對共有私有方法屬性的實現自然。

    關於性能:定義在原型上的方法,所有實例共享同一方法,不會像實例級方法那樣要爲每個實例單獨分配,因此性能僅次於面向過程的調用風格。

    關於擴展:假如類的實現很複雜,需要私有過程、static 變量的時候,這樣寫可以在不犧牲性能的前提下最大限度保持外部乾淨。

    另外,可以用多數編輯器支持的代碼摺疊隱藏細節也算是這種寫法額外的福利。

    另參見:http://stackoverflow.com/questions/1441212/javascript-instance-functions-versus-prototype-functions


    關於題中的第一種(Instance Functions),如果需要私有屬性的話是可以考慮的做法,如果需要性能的話還是全部公有並改爲 Prototype Functions 比較好。

    第一種的「正確」用法:

    function Rectangle(w, h) {
        this.area = function() {
            return w * h;
        }
    }
    

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 14:45:48

    嗯。。第二种方法是有问题的,Rectangle1.prototype.area=function...应该放在Rectangle1构造函数的外面。

    function   Rectangle1(w,h){
    this.width=w;
    this.height=h;
    }
    }
    Rectangle1.prototype.area=function  ()  {
        return   this.width*this.height;
    }
    

    至于为什么设置prototype好……标准吧,因为函数不属于对象啊

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 14:45:48

    使用原型的话,内存里只需要一份 area function 的拷贝就可以了。

    如果是每次在构造函数里赋值的话,那样每 new 一次就会产生一个 area function, 是一种浪费。

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 14:45:48

    性能问题:由于各种 runtime engine 优化的原因,使用原型的性能好很多。

    http://stackoverflow.com/questions/8729714/closures-vs-classes-for-encapsulation/8729939#8729939 里面有说,时间差距 20x,空间差距 O(N)。

    reply
    0
  • Cancelreply