最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

JavaScript进阶系列—原型

来源:动视网 责编:小采 时间:2020-11-27 20:25:32
文档

JavaScript进阶系列—原型

JavaScript进阶系列—原型:属性查找原型属性性能扩展内置类型的原型总结JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型。经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。 实现传统的类继承模型是很简单,但是实现 Java
推荐度:
导读JavaScript进阶系列—原型:属性查找原型属性性能扩展内置类型的原型总结JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型。经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。 实现传统的类继承模型是很简单,但是实现 Java


  • 属性查找

  • 原型属性

  • 性能

  • 扩展内置类型的原型

  • 总结

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

    经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。 实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多。 (It is for example fairly trivial to build a classic model on top of it, while the other way around is a far more difficult task.)

    JavaScript 是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的。

    不同之处在于 JavaScript 使用原型链的继承方式。

    function Foo() {
     this.value = 42;
    }
    Foo.prototype = {
     method: function() {}
    };
    
    function Bar() {}
    
    // 设置Bar的prototype属性为Foo的实例对象
    Bar.prototype = new Foo();
    Bar.prototype.foo = 'Hello World';
    
    // 修正Bar.prototype.constructor为Bar本身
    Bar.prototype.constructor = Bar;
    
    var test = new Bar() // 创建Bar的一个新实例
    
    // 原型链
    test [Bar的实例]
     Bar.prototype [Foo的实例] 
     { foo: 'Hello World' }
     Foo.prototype
     {method: ...};
     Object.prototype
     {toString: ... /* etc. */};

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

    属性查找

    一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。

    到达原型链的顶部 - 也就是 Object.prototype - 但是仍然没有找到指定的属性,就会返回 undefined。

    注意:不要使用Bar.prototype = Foo,因为这不会执行 Foo 的原型,而是指向函数 Foo。 因此原型链将会回溯到Function.prototype 而不是Foo.prototype,因此method 将不会在 Bar 的原型链上。

    原型属性

    属性用来创建原型链时,可以把任何类型的值赋给它(prototype)。 然而将原子类型赋给 prototype 的操作将会被忽略。

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

    而将对象赋值给 prototype,正如上面的例子所示,将会动态的创建原型链。

    性能

    如果一个属性在原型链的上端,则对于查找时间将带来不利影响。特别的,试图获取一个不存在的属性将会遍历整个原型链。

    并且,当使用 for in 循环遍历对象的属性时,原型链上的所有属性都将被访问。

    扩展内置类型的原型

    一个错误特性被经常使用,那就是扩展 Object.prototype 或者其他内置类型的原型对象。

    这种技术被称之为 monkey patching 并且会破坏封装。虽然它被广泛的应用到一些 JavaScript 类库中比如 Prototype, 但是我仍然不认为为内置类型添加一些非标准的函数是个好主意。

    扩展内置类型的唯一理由是为了和新的 JavaScript 保持一致,比如Array.forEach。

    总结

    在写复杂的 JavaScript 应用之前,充分理解原型链继承的工作方式是每个 JavaScript 程序员必修的功课。 要提防原型链过长带来的性能问题,并知道如何通过缩短原型链来提高性能。 更进一步,绝对不要扩展内置类型的原型,除非是为了和新的 JavaScript 引擎兼容。

    注:这是编程领域常用的一种方式,称之为 Backport,也就是将新的补丁添加到老版本中。

    文档

    JavaScript进阶系列—原型

    JavaScript进阶系列—原型:属性查找原型属性性能扩展内置类型的原型总结JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型。经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。 实现传统的类继承模型是很简单,但是实现 Java
    推荐度:
    标签: js javascript 原型
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top