zoukankan      html  css  js  c++  java
  • 高级javascript---原型和原型继承

    高级javascript---原型和原型继承

    在 JavaScript 中,prototype 是函数的一个属性,同时也是由构造函数创建的对象的一个属性。 函数的原型为对象。 它主要在函数用作构造函数时使用。

    function Vehicle(wheels, engine) {
        this.wheels = wheels;
        this.engine = engine;
    }

    在上面的示例中,Vehicle 函数的原型是使用 Vehicle 构造函数实例化的任何对象的原型。

    可以使用 prototype 属性向对象添加属性和方法,甚至于已创建的对象也是如此:

    var testVehicle = new Vehicle(2, false);
    Vehicle.prototype.color = "red";
    var testColor = testVehicle.color;
    

      

    testColor 的值为“red”。

    你甚至可以向预定义的对象添加属性和方法。 例如,你可以在 String 原型对象上定义一个 Trim 方法,脚本中的所有字符串都将继承该方法。

    String.prototype.trim = function()
    {
        // Replace leading and trailing spaces with the empty string
        return this.replace(/(^s*)|(s*$)/g, "");
    }
    var s = "    leading and trailing spaces    ";
    // Displays "    leading and trailing spaces     (35)"
    window.alert(s + " (" + s.length + ")");
    // Remove the leading and trailing spaces
    s = s.trim();
    // Displays "leading and trailing spaces (27)"
    window.alert(s + " (" + s.length + ")");

    使用原型通过 Object.create 从一个对象派生另一个对象

    prototype 对象可用于从一个对象派生另一个对象。 例如,你可以使用 Object.create 函数派生使用我们之前定义的 Vehicle 对象的原型(以及所需的任何新属性)的新对象Bicycle。

    var Bicycle = Object.create(Object.getPrototypeOf(Vehicle), {
        "pedals" :{value: true}
    });

    Bicycle 对象具有属性 wheels、engine、color 和 pedals,并且其原型为 Vehicle.prototype。 JavaScript 引擎会查找 Bicycle 的 pedals 属性,并查看原型链以便查找Vehicle 的 wheels、engine 和 color。

    Hh924508.collapse_all(zh-cn,VS.94).gif更改对象的原型

    在 Internet Explorer 11 中,可以通过 __proto 属性用新原型替换对象或函数的内部原型。 使用此属性时,将继承新原型的属性和方法以及其原型链中的其他属性和方法。

    以下示例演示如何更改对象的原型。 此示例演示当更改对象原型时,对象的继承属性将如何更改。

    function Friend() {
        this.demeanor = "happy";
    }
    
    function Foe() {
        this.demeanor = "suspicious";
    }
    
    var friend = new Friend();
    var foe = new Foe();
    
    var player = new Object();
    player.__proto__ = foe;
    
    friend.ally = "Tom";
    
    if (console && console.log) {
        console.log(player.demeanor === "happy" );      // Returns false
        console.log(player.demeanor === "suspicious");  // Returns true
        console.log(player.ally === "Tom");             // Returns false
        // Turn the foe to a friend.
        player.__proto__ = friend;
        console.log(player.demeanor === "happy");       // Returns true
        console.log(player.demeanor === "suspicious");  // Returns false
        console.log(player.ally === "Tom");             // Returns true
    }

    上面是摘自http://msdn.microsoft.com/zh-cn/library/hh924508(v=vs.94).aspx上的原文。

    下面是我从慕客网上看到的一个问题,仔细分析之后感觉挺有意思,于是记下录来。

    仔细分析 Man.prototype = new People 与 Man.prototype = People.prototype 这两种继承的区别

    function People (){
            this.name = 'frog';
            this.age = 29;
        }
        
        People.prototype.getName = function(){
            return this.name;
        }
        
        function Man(){
           this.name = 'rat';
           this.age = 3;
        }
        
        Man.prototype = People.prototype;
    
        //某一天,新来的小伙伴修改了这个方法
        Man.prototype.getName = function(){
            return this.age;
        }
        
        var p = new People;
        var n = p.getName();
        console.log(n); // 输出29而不是 frog 
        //说明直接用原开链,父类会被子类影响

     所以一般不直接用对象原型,而是用对象的实例
    function People (){
            this.name = 'frog';
            this.age = 29;
        }
        
        People.prototype.getName = function(){
            return this.name;
        }
        
        function Man(){
           this.name = 'rat';
           this.age = 3;
        }
        
        Man.prototype = new People;
    
        //再次修改原型上的方法
        Man.prototype.getName = function(){
            return this.age;
        }
        
        var p = new People;
        var n = p.getName();
        console.log(n);  // frog 说明父类没有受影响

    这样改,子类的修改就不会影响到父类了,不过这样做有一个缺点,一是每次实例化Man的时候都会new People, 二是People上的属性也会继承到Man上来,通常我们只想要继承父对象上的方法,不需要它的属性,所以,就出现了下面的用法

    f = function(){};
    f.prototype = People.prototype;
    Man.prototyep = new f();
    通过这样中转一下,就可以只继承People上的方法,而不承它的属性,同时子类的修改,不会影响到父类了。

    如果您觉得这文章对您有帮助,请点击【推荐一下】,想跟我一起学习吗?那就【关注】我吧!

  • 相关阅读:
    os.path.join()
    图像旋转后出现黑点
    surging 微服务引擎 1.0 正式发布
    基于docker 如何部署surging分布式微服务引擎
    剥析surging的架构思想
    如何使用thrift 服务引擎组件
    谈谈surging 与多语言混合微服务构思
    surging 社区版本支持.net core 3.1
    surging 微服务引擎 -协议主机的Behavior特性
    谈谈surging 微服务引擎 2.0的链路跟踪和其它新增功能
  • 原文地址:https://www.cnblogs.com/afrog/p/4033670.html
Copyright © 2011-2022 走看看