无论什么时候,只要创建了一个函数,就会根据一组特定的行为规则为该函数创建一个prototype属性,该属性自动获得一个constructor(构造函数)属性,该constructor包含一个指向prototype所在函数的指针。如果这个函数被用在创建自定义函数的场景中,那么该函数就称为构造函数。比如下面的一个场景:
function Person(name){ this.name = name; } Person.prototype = { getName:function(){ return this.name; } } var p = new Person("Nicholas"); console.log(p.getName());
同样的道理,我们也可以推断js中原始数据类型:字符串(String)、数字(Number)、数组(Array)、对象(Object)、日期(Date)等,这些数据类型也是作为构造函数来实现的。
比如我们知道的很多对数组操作的方法concat、join、push等,这些方法应该都是在prototype中定义的,只不过这些固有数据类型的prototype属性都是只读的。这些固有数据类型的prototype属性设置为只读也是可以理解的,因为如果改了这些数据类型的prototype那么这些数据类型的预定义方法就没有了。但是我们可以向这些数据类型中添加扩展自己的方法,如
Array.prototype.min = function(){ var min = this[0]; for(var i = 0; i < this.length; i++){ if(this[i] < min){ min = this[i]; } } return min; } var arr = new Array(1,56,34,12); console.log(arr.min());
我们通过扩展prototype属性的方法扩展固有数据类型的方法,这里有一个陷阱,就是我们扩展的这个方法,通过for---in循环数组时会被循环出来,
解决这个问题也很简单,只需要用hasOwnproperty()判断一下即可,如
var arr2 = new Array("worker",23,"teacher","student",88); for(var i in arr2){ if(arr2.hasOwnProperty(i)){ console.log(arr2[i]); } }