权威指南学习心得-类

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

当使用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(){};//这个构造函数有名字
原文地址:https://www.cnblogs.com/yhf286/p/5064718.html