在JavaScript中,函数时一个包括属性和方法的Function类型的对象。而原型(Prototype)就是Function类型对象的一个属性。
在函数定义时就包含了protoype属性,它的初始值是一个空对象。在JavaScript中并无定义函数的原始类型,因此原型能够是任何类型。
原型是用于保存对象的共享属性和方法的,原型的属性和方法并不会影响函数自己的属性和方法。数组
Function类型的属性 -> 全部函数都具备的属性 console.log(Function.prototype); // 定义函数 function fn(){ console.log('this is function'); } // 原型的默认值是空对象 console.log(fn.prototype); // 函数包含构造函数 -> 全部引用类型其实都是构造函数 console.log(Number.prototype); console.log(Object.prototype); var result = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor'); console.log(result);
经过下面代码方式获取对象的原型,从而设置共享的属性和方法。函数
function fn(){ console.log('this is function'); } // 使用访问对象的属性语法结构 console.log(fn.prototype); console.log(fn['prototype']); // Object类型提供getPrototypeOf()方法 console.log(Object.getPrototypeOf(fn));
function fn(){ console.log('this is function'); } // 变量proto也是一个空对象 // var proto = fn.prototype; // 新增属性或方法 // proto.name = '张无忌'; fn.prototype.name = '张无忌'; console.log(fn.prototype); // defineProperty() Object.defineProperty(fn.prototype, 'age', { value : 18, enumerable : true }); console.log(fn.prototype);
1.自有属性:经过对象的引用添加的属性。其余对象可能无此属性;即便有,也是彼此独立的属性。
2.原有属性:从原型对象中继承来的属性,一旦原型对象中属性值改变,全部继承自该原型的对象属性均改变。this
// 定义构造函数 function Hero(){ this.name = '张无忌'; this.sayMe = function(){ console.log('this is function'); } } // 操做构造函数Hero的原型 Hero.prototype.age = 18; // 利用构造函数来建立对象 var hero = new Hero(); console.log(hero); // 为构造函数的原型新增的属性 -> 构造函数建立的对象中依旧能够访问 console.log(hero.age);// 18 // 对象hero中不存在age属性 var result = Object.getOwnPropertyDescriptor(hero, 'age'); console.log(result);
function Hero(){ // this.name = '张无忌';// 自有属性 } // Hero.prototype.name = '周芷若'; var hero = new Hero(); /* Object.hasOwnProperty(prop)方法 * 做用 - 判断当前指定属性是否为自有属性 * 参数 * prop - 表示指定属性名称 * 返回值 - 布尔值 * true - 表示存在指定的自有属性 * false - 表示不存在指定的自有属性 */ // console.log(hero.hasOwnProperty('name'));// true /* 使用in关键字检测对象的属性 * 做用 - 判断对象中是否存在指定属性(自有属性或原型属性) * 返回值 - 布尔值 * true - 表示存在指定的属性 * false - 表示不存在指定的属性 */ console.log('name' in hero);
经过原型能够为指定构造函数或对象扩展其属性或方法。prototype
function fn(){ console.log('this is function'); } // 变量proto也是一个空对象 // var proto = fn.prototype; // 新增属性或方法 // proto.name = '张无忌'; fn.prototype.name = '张无忌'; console.log(fn.prototype); // defineProperty() Object.defineProperty(fn.prototype, 'age', { value : 18, enumerable : true }); console.log(fn.prototype);
经过构造函数或对象的自有属性能够重写原型的属性调试
// 定义构造函数 function Hero(){ this.name = '张无忌'; } // 构造函数的原型 Hero.prototype.name = '周芷若'; // 构造函数建立对象 var hero = new Hero(); // 自有属性与原型属性同名时,默认访问的是自有属性 -> 自有属性的优先级别高于原型属性 console.log(hero.name);// 张无忌 // 删除对象的属性 delete hero.name; // 从新访问对象的属性 console.log(hero.name);// 周芷若
经过delete关键字能够删除对象的属性,若是该对象即具备原型属性又具备自有属性,首先就要删除自有属性,再删除原型属性。code
function Hero(){} Hero.prototype = { name:'Mary',salary:3800 }; var hero = new Hero(); hero.name = "Tom"; delete hero.name;//删除Tom console.log(hero.name);//Mary delete hero.name;//删除Mary console.log(hero.name);//undefined
每一个对象中都会基友一个isPrototypeOf()方法,该方法用来判断一个对象是不是另外一个对象的原型。对象
// 经过初始化器方式定义对象 var obj = { name : '张无忌' } // 定义构造函数 function Hero(){} // 将对象obj赋值给构造函数Hero的原型 Hero.prototype = obj; // 经过构造函数建立对象 var hero = new Hero(); // 判断指定对象是不是另外一个对象的原型 var result = obj.isPrototypeOf(hero); console.log(result);
——proto——属性继承
// 经过初始化器方式定义对象 var obj = { name : '张无忌' } // 定义构造函数 function Hero(){} // 将对象obj赋值给构造函数Hero的原型 Hero.prototype = obj; // 经过构造函数建立对象 var hero = new Hero(); // 判断指定对象是不是另外一个对象的原型 var result = obj.isPrototypeOf(hero); console.log(result);
上述代码中说明hero对象存在一个指向构造函数Hero的原型,这个连接被叫作——proto——属性。
须要注意的是——proto——属性与prototype属性并不等价。——proto——属性只能调试时使用。
——proto——属性是指定对象的属性。
prototype属性是指定构造函数的属性。ip
JavaScript中的内置对象有些也具备prototype属性,利用内置对象的prototype属性能够为内置对象扩展属性或方法。
经过原型扩展内置对象的属性和方法很是灵活,根据个性化要求制定JavaScript语言的具体内容。通常建议谨慎使用这种方法,若是JavaScript的版本更新是可能会提供个性化的属性或方法,致使冲突。get
Object.prototype.sayMe = function(){ console.log('this is sayMe function'); } // 经过Object构造函数建立对象 var obj = new Object(); obj.sayMe(); Array.prototype.inArray = function(color){ // this - 表示当前的数组 for(var i = 0, len = this.length; i < len; i++){ if(this[i] === color){ return true; } } return false; } var arr = ["red", "green", "blue"]; console.log(arr.inArray("red")); //true console.log(arr.inArray("yellow")); //false