关于动态原型方法绑定的一些问题《JavaScript高级程序设计》?
天蓬老师
天蓬老师 2017-04-11 09:11:57
0
6
350

两端代码,不同的地方在于Triangle.prototype = new Polygon();放置位置不同

第一段代码:

function Polygon(iSides){ this.sides = iSides; if(typeof Polygon._initialized == 'undefined'){ Polygon.prototype.getArea = function() { return 0; }; Polygon._initialized = true; } } function Triangle(iBase,iHeight){ Polygon.call(this,3); this.base = iBase; this.height = iHeight; if(typeof Triangle._initialized == 'undefined'){ Triangle.prototype = new Polygon();//这里不同******* Triangle.prototype.getArea = function(){ return 0.5*this.base*this.height; } Triangle._initialized = true; } } var a =new Polygon(3); var b =new Triangle(4,5); var c =new Triangle(6,7); console.log(a); console.log(b); console.log(c);

输出结果如下图所示:
第一个实例化的Triangle()没有绑定原型方法

第二段代码:

function Polygon(iSides){ this.sides = iSides; if(typeof Polygon._initialized == 'undefined'){ Polygon.prototype.getArea = function() { return 0; }; Polygon._initialized = true; } } function Triangle(iBase,iHeight){ Polygon.call(this,3); this.base = iBase; this.height = iHeight; if(typeof Triangle._initialized == 'undefined'){ Triangle.prototype.getArea = function(){ return 0.5*this.base*this.height; } Triangle._initialized = true; } } Triangle.prototype = new Polygon();//移动到了这里******* var a =new Polygon(3); var b =new Triangle(4,5); var c =new Triangle(6,7); console.log(a); console.log(b); console.log(c);

输出结果如下图所示:
第一个实例化的Triangle()绑定了原型方法

两端代码的目的都是让Triangle使用动态原型方法继承Polygon,我认为第一个实例化的Triangle()能够绑定原型方法,但结果却不是,书上说,

在代码运行前,对象已被实例化,并与原始的prototype对象联系在一起了。虽然用极晚绑定可使对原型对象的修改正确地反映出来,但替换prototype对象却不会对该对象产生任何影响。 只要未来的对象实例才会反映出这种改变,这就使第一个实例变得不正确。 (《JavaScript高级程序设计》100页)

这里的 在代码运行前,对象已经被实例化又是什么意思,为什么第一个实例会不正确呢。。。?
不明白书上说的在代码

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

reply all (6)
伊谢尔伦

你想想,生成对象(或者叫实例化)是通过构造函数来完成的,在调用构造函数的时候,一开始就选用了之前的原型,所以这次调用产生的对象绑定的是原来的原型。新的原型是在构造函数中绑定的,已经不能用在当次实例化的时候,只能在下次实例化的时候起作用了。

一般情况下,不会有人把处理原型的事情放在构造函数里来进行。这段代码的出现,也只是为了说清楚晚绑定吧。

    左手右手慢动作

    在情况一的Triangle构造函数顶部中,添加一条log,然后就真相大白了

      阿神

      看下这个链接,和你的问题是一个原因。

        阿神

        在 JS 中创建一个对象(A)的过程可以说是一个“克隆”的过程,即参照一个对象(B)来进行克隆,B 就被称为“克隆”出的 A 的原型,而这个原型 B 在 JS 中是被赋予给被克隆出的对象(A)的构造函数(构造函数可以比拟成工厂中生产产品的一套流程,每次新建一个对象时,都会进行这套流程)的 prototype 属性,所以更准确的说是对象 A 的构造函数拥有原型。在第一段代码中,在创建对象 b 之前,它的构造函数并没有人为的设置原型,所以默认为 Object,所以在创建 b 的时候,b 参照的对象为 Object,所以自然不会有 getArea() 方法。

          伊谢尔伦

          1.new的时候创建了一个空的对象。
          2.将构造函数的原型赋(假设为a)给了这个新的对象
          3.进行{}.属性==一系列操作
          //
          第一种构造函数的原型指向变了指向了b,但是实例化的实例的原型指针已经确定了指向了a。不会受影响。

          虽然用极晚绑定可使对原型对象的修改正确地反映出来,但替换prototype对象却不会对该对象产生任何影响。

          就是说‘对原型对象的修改’,改的是a;用=赋值‘替换prototype对象’,是直接指向了b,而没有修改之前实例的原型指针。

            Peter_Zhu

            高级程序设计 6.2.3原型模式第4点原型的动态性 重点 必考点

              Latest Downloads
              More>
              Web Effects
              Website Source Code
              Website Materials
              Front End Template
              About us Disclaimer Sitemap
              php.cn:Public welfare online PHP training,Help PHP learners grow quickly!