权威指南学习心得-类

构造函甚至没必要返回这个新建立的对象,构造函数会自动建立对象,而后将构造函数看成为这个对象的方法来调用一次,最后返回这个新对象。javascript

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

r instanceof Range//若是r继承自range.prototype,则返回trueecmascript

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

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

若是你检测对象的原型链上是否存在某个特定的原型对象,有没有不使用构造函数做为中介的方法么?答案是确定的,能够使用isPrototypeOf()方法。spa

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

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属性的值是一个函数对象。code

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属性为对象提供哦了类blog

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(/function\s*([^()]*)\(/)[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(/function\s*([^(]*)\(/)[1];
};
function test(){};
var p=new test();
console.log(type(p));

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

var complex=function(x,y){};//这个构造函数没有名字

var range=function range(){};//这个构造函数有名字
相关文章
相关标签/搜索