zoukankan      html  css  js  c++  java
  • 函数原型

    原型链概要

    Prototype属性是javascript为每个Function实例创建的一个对象。Prototype属性来自Function构造函数,Function构造函数为每个实例赋一个prootype属性

    var myFunction = function() {};
    console.log(myFunction.prototype);//输出myFunction{}
    //默认的prototype属性是Object对象
    console.log(typeof myFunction.prototype); //输出object
    
    myFunction.prototype = {}; //设置prototype属性为空对象 console.log(myFunction.prototype);//输出空对象,object{}

    原型链的最后是Object.prototype

    例如:因为在myArray.foo,Array.prototype.foo,Object.prototype.foo中没有找到foo,所以foo是undefined,所以最后输出的是undefined

     var myArray = {};
    console.log(myArray.foo);//输出undefined,

    原型链返回在链中找到的第一个匹配结果

    与作用域链一样,原型链在查找时将使用它找到的第一个值

    查找的顺序为:自身对象----〉构造函数----〉Object对象

    如下例子查找顺序为:myArray.foo->Array.prototype.fooàObject.prototype.foo

     Object.prototype.foo = "object-foo";
            Array.prototype.foo = "array-foo";
            var myArray = [];
    
            console.log(myArray.foo); //输出array-foo
            myArray.foo = "bar";
            console.log(myArray.foo);//输出bar 

    用新对象替换prototype属性会删除默认函数属性

    可以用一个新值来替换prototype属性的默认值,但是这样会删除原型对象中的默认得constructor属性,除非手动指定一个。

     var foo = function Foo() {
            };
    
            foo.prototype = {};
            var fooInstance = new foo();
            console.log(fooInstance.constructor === foo); //输出false,破坏了引用
            console.log(typeof fooInstance.constructor); //输出function
            foo.prototype = { constructor: foo }; //重新指定
            console.log(fooInstance.constructor === foo); //输出false,因为fooInstance在重新指定之前已经实例化,所以取不到最新值
            console.log(typeof fooInstance.constructor); //输出function
            var bar = new foo();
            console.log(bar.constructor === foo);//输出true
            console.log(typeof bar.constructor); //输出function

    继承原型属性的实例总是能够获得最新值

    实例总是能够从原型获得最新的值,不管何时被实例化,更改或附加,在这种意义上,prototype属性是动态的。

    var foo = function Foo() { };
            foo.prototype.x = 1;
            var fooInstance = new foo();
            console.log(fooInstance.x);//输出1
            foo.prototype.x = 2;
            console.log(fooInstance.x);//输出2
            console.log(foo.x);//输出undefined
    
    通过替换默认原型对象的方式赋值,例如:
    
    var foo = function Foo() { };
            foo.prototype={x:1}
            var fooInstance = new foo();
            console.log(fooInstance.x);//输出1
            foo.prototype.x = 2;
            console.log(fooInstance.x);//输出2
            console.log(foo.x);//输出undefined

    又例如:

    var foo = function Foo() { };
            foo.prototype={x:1}
            var fooInstance = new foo();
            console.log(fooInstance.x);//输出1
            foo.prototype={x:2}
            console.log(fooInstance.x);//输出1,因为fooInstance对象在原型foo.prototype={x:2}之前,所以获取不到最新的原型值
            console.log(foo.x);//输出undefined

    用新对象替换prototype属性不会更新以前的实例

    创建一个实例时,该实例将在实例化时被绑定到“刚完成”的原型。

    提供一个新对象做为prototype属性不会更新已创建实例和原型之间的连接。

    例如:

    var foo = function Foo() { };
            foo.prototype.x = 1;
            var fooInstance = new foo();
            console.log(fooInstance.x); //输出1
            //使用新Object()对象覆盖Foo的原型 
            foo.prototype = { x: 2 };
            console.log(fooInstance.x);//输出1,fooInstance依然是引用的初始化的原型对象
            
            //该新实例目前引用的就是新原型对象了(也就是{x:2})
            var newFoolInstance = new foo();
            console.log(newFoolInstance.x); //输出2

    一旦开始创建实例,就不应用一个新对象来替换对象的原型

     

    用户自定义构造函数像原生构造函数一样原型继承

    //用户自定义构造函数像原生构造函数一样原型继承
            var Person = function() {
            };
            Person.prototype.legs = 2;
            Person.prototype.arms = 2;
            Person.prototype.countLimbs = function() {
                return this.legs + this.arms;
            };
            var chuck = new Person();
            console.log(chuck.countLimbs());//输出4
    
    
      //为了很好的展示原型链,可以创建一个构造函数,通过给构造函数传值,而覆盖原型的值
            var Person = function(legs, arms) {
                //隐藏原型的值
                if (legs != undefined) {
                    this.legs = legs;
                }
                if (arms != undefined) {
                    this.arms = arms;
                }
            };
            Person.prototype.legs = 2;
            Person.prototype.arms = 2;
            Person.prototype.countLimbs = function() {
                return this.legs + this.arms;
            };
            var chuck = new Person(0, 0);
            console.log(chuck.countLimbs());//输出0

    创建继承链

    只需 要将对象实例做为要继承该对象实例的函数的prototype的属性值

    例如:chef对象需要继承Person(),只需要将chef.prototype指向实例化的Person()

    即:chef.prototype=new Person();

    //创建继承链
            var Person = function() {
                this.bar = 'bar';
            };
            Person.prototype.foo = "foo";
    
            var chef = function() {
                this.goo = "goo";
            };
    
            chef.prototype = new Person(); //创建继承
            var cody = new chef();
            console.log(cody.foo); //输出foo
            console.log(cody.goo); //输出goo
            console.log(cody.bar);//输出bar
  • 相关阅读:
    在Springboot 中使用 flyway
    Ryu 学习资料总结
    OpenDaylight 学习资料整理
    在 Ubuntu16.04 上安装 etcd
    ovs 连接 Floodlight 控制器
    etcd 学习资料整理
    Floodlight 学习资料整理
    算法用例
    数据库
    他山之石
  • 原文地址:https://www.cnblogs.com/alice626/p/5210907.html
Copyright © 2011-2022 走看看