美文网首页
JavaScript原型与原型链终极详解

JavaScript原型与原型链终极详解

作者: __马帅傅__ | 来源:发表于2017-09-14 12:07 被阅读0次

    JavaScript不包含传统的类继承模型,而是使用prototypal原型模型。

    一、原型

         刚开始写代码的时候,如下代码:

    1.原型使用方式1:

          在使用原型之前,将代码做些修改:

          然后,通过给Calculator对象的prototype属性赋值来设定对象的原型。

    2.原型使用方式2:

          在赋值原型prototype的时候使用function立即执行的表达式来赋值。

          Calculator.prototype = function(){}(); 

          它的好处在于可以封装私有的function,通过return的方式暴露出简单的使用名称,以达到public/private的效果,修改后的代码如下:

    3.分步声明:

      上述使用原型的时候,有一个限制就是一次性设置了原型对象,分别设置原型的每个属性如下:

    4.重写原型:

        *注意:重写的代码需要放在最后,才能覆盖前面的代码。在使用第三方JS库的时候,往往有时候他们定义的原型方法不能满足我们的需要,但是又离不开这个类库。这个时候我们就需要重写他们的原型中一个或多个属性或function,我们可以通过继续声明同样的add代码的形式来达到重写前面的add功能,代码如下:

    二、原型链

    1.实例:

         上面的例子中,test对象从Bar.prototype和Foo.prototype中继承下来,因此它能访问Foo的原型方法method,它也能访问那个定义在原型上的Foo实例属性value。需要注意的是new Bar()不会创建一个新的Foo实例,而是反复使用它原型上的那个实例;因此,所有的Bar实例都会共享相同的value属性。

    2.属性查找:

           当查找一个对象的属性的时候,JavaScript会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶端,也就是Object.prototype,但是没有找到指定的属性,就会返回undefined。

         属性在查找的时候是先查找自身的属性,如果没有再查找原型,再没有再往上走,一直查到Object的原型上,所以在某种层面上说,用for in 语句遍历属性的时候,效率也是个问题。 

         需要注意的是,我们可以赋值任何类型的对象到原型上,但是不能赋值原子类型的值,比如如下代码是无效的。

         function Foo(){ };           Foo.prototype = 1;  //无效

    3.hasOwnProperty函数

            hasOwnProperty是Object.prototype的一个方法,可以判断出一个对象是否包含自定义属性而不是原型链,因为hasOwnProperty是JavaScript中唯一一个处理属性,但是不查找原型链的函数。

          只有hasOwnProperty可以给出正确和期望的结果,这在遍历对象属性时会很有用。JavaScript不会保护hasOwnProperty被非法占用,因此如果一个对象碰巧存在这个属性,就需要使用外部的hasOwnProperty函数来获取正确的结果。

          我们没办法改变for in 语句的行为,所以想过滤结果就只能使用hasOwnProperty方法,代码如下:

          这个版本的代码是唯一一个正确的写法。如果不使用hasOwnProperty,则这段代码在原生对象原型(比如Object.prototype)被扩展的时候可能会出错。

    相关文章

      网友评论

          本文标题:JavaScript原型与原型链终极详解

          本文链接:https://www.haomeiwen.com/subject/mrzrsxtx.html