zoukankan      html  css  js  c++  java
  • 权威指南学习心得-类

    构造函甚至不必返回这个新创建的对象,构造函数会自动创建对象,然后将构造函数当作为这个对象的方法来调用一次,最后返回这个新对象。

    当使用instanceof运算符来检测对象是否属于某个类时会用到构造函数

    r instanceof Range//如果r继承自range.prototype,则返回true

    实际上instranceof运算符并不检查r是否由range构造函数初始化而来,而是检查r是否继承自range.prototype.

    如果o继承自c.prototype,则表达式o instanceof c值为true,这里的继承可以不是直接继承,如果o所继承的对象继承自另一对象,后一个对象继承自c.prototype,这个表达式的运算结果也是true。

    如果你检测对象的原型链上是否存在某个特定的原型对象,有没有不使用构造函数作为中介的方法么?答案是肯定的,可以使用isPrototypeOf()方法。

    constructor 另一种识别对象是否属于某个类的方法是constructor属性。因为构造函数是类的公共标识符,所以最直接的方法就是使用constructor属性。

    function typeAndValue(x){
      if(x==null)return "";
      switch(x.constructor){
        case Number:return "Nuber: "+x;
        case String: return "String:'"+x+"'";
        case Date: return "Date:"+x;
           case RegExp: return "RegExp"+x;
      }
    }
    console.log(typeAndValue(1));//Nuber: 1
    console.log(typeAndValue("1"));//String:'1'
    console.log(typeAndValue(new Date()));//Date:Tue Dec 22 2015 19:42:15 GMT+0800 (中国标准时间)

    任何javascript函数都可以用作构造函数,并且调用构造函数是需要用到一个prototype属性的。因此,每个javascript函数(除了ecmascript 5中的Function.bind方法返回的函数之外)都自动拥有一个prototype属性。这个属性的值是一个对象。这个对象包含唯一一个不可枚举属性constructor。constructor属性的值是一个函数对象。

    function f(){};
    var p=f.prototype;
    var c=p.constructor;
    console.log(c);//function f(){}
    console.log(p);//f {}
    console.log(c===f);//true

    对任意函数F.prototype.constructor==F;

    可以看到构造函数的原型中存在预先定义好的constructor属性,这意味这对象通常继承的constructor均指代它们的构造函数,由于构造函数是类的公共标识,因此这个constructor属性为对象提供哦了类

    var o=new F();

    o.constructor===F;//true

    range类使用它自身的一个新对象重写了预定义的rang.prototype对象,这个新定义的原型对象不含有constructor属性。因此range类的实例也不含有constructor属性,我们可以通过补救来修正这个问题,显示的给原型添加一个构造函数:

    function Range(){
      this.x=1;
      this.y=2;
    };
    Range.prototype={
      constructor:Range
    };
    
    
    var p=new Range();
    
    console.log(p.constructor);

    另一种常见的解决方法是使用预定义的原型对象,预定义的原型对象包含construtor属性,然后依次给原型对象添加方法

    类的扩充

    String.prototype.trim=String.prototype.trim||function(){
      if(!this)return this;
      return this.replace(/^s+|s+$/g,"");
    };
    
    console.log("   sdf  ".trim());//sdf
    
    Function.prototype.getName=function(){
      
      return this.Name|| this.toString().match(/functions*([^()]*)(/)[1];
      
    };
    function test(){
      
    }
    console.log(test.getName());//test

    在javascipt中并非所有的对象都包含constructor属性。在每个新创建的函数原型上默认会有constructor属性,但我们常常忽略原型上的constructor属性。比如下面的实例就没有constructor属性

    function F(){
      
    }
    F.prototype={};
    
    var o=new F();
    
    function inhernit(o){
      if(o==null) return null;
      function f(){};
      f.prototype=o;
      return new f();
      
    }
    
    var t=inhernit(o);
    function type(o){
      var t,c, n;//type,class ,name
      //处理null值得特殊情形
      if(o===null) return "null";
      if(o!==o) return "nan";
      if((t=typeof o)!=="object"){
        return t;
      }
      
      if((c=classof(o))!=="Object"){
        return c;
      }
      if(o.constructor&&typeof o.constructor==="function"&&(n=o.constructor.getName())){
        return n;
      }
      
      return "Object";
    }
    function classof(o){
      return Object.prototype.toString.call(o).slice(8,-1);
    }
    Function.prototype.getName=function(){
      if("name" in this) return this.name;
      return  this.name=this.toString().math(/functions*([^(]*)(/)[1];
    };
    function test(){};
    var p=new test();
    console.log(type(p));

    并不是所有的对象都具有constructor属性,此外,并不是所有的函数都有名字,如果使用不带名字的函数定义表达式定义一个构造函数,那么getName方法则返回空字符串。

    var complex=function(x,y){};//这个构造函数没有名字
    
    var range=function range(){};//这个构造函数有名字
  • 相关阅读:
    韩寒做错了(update 4 12)。
    放弃IE6。
    阿弥陀佛,我没有“抄袭”。
    婚姻。
    爆牙齿饭否?
    地震之后——和妈妈对话。
    8年前,《西班牙,我为你哭泣。》
    在等决赛中提问。
    地震之后——中国互联网在黑夜中哭泣。
    年轻。
  • 原文地址:https://www.cnblogs.com/yhf286/p/5064718.html
Copyright © 2011-2022 走看看