〇 每个函数都拥有prototype属性,而该属性所储存的就是原型对象
1)原型属性——
上面我们测试了foo()函数的
1) length属性(length属性除了可以用在数组中,还可以用于记录函数参数的数量)
2)来自原型的constructor property属性(该属性实际上是一个之指向用于创建该对象的构造器函数的引用),其引用就是Function()这个构造器函数
3)来自原型的prototype属性(每个函数的prototype属性都指向了一个对象,并且它只有在该函数是构造器时才会发挥作用,并且它创建的属性可以当做函数自身属性使用)
- 利用原型属性添加方法和属性
function Gadget(name,color){ this.name = name ; this.color = color; this.whatAreYou = function () { return 'I am a' + this.color + '' + this.name; } ; }Gadget.prototype.price = 100;Gadget.prototype.rating= 3;Gadget.prototype.getInfo = function () { return 'Rating:' + this.rating +',price:' + this.price; }/*我们还可以避开这种逐一添加的繁琐*/Gadget.prototype = { price:100, rating:... /*and so on...*/ }
- 使用原型的方法与属性
/*接下来,我们就可以直接用该构造器来新建对象了*/var newtoy = new Gadget('赛车','白色');newtoy.name; /*赛车*/newtoy.color; /*白色*/newtoy.whatAreYou() /*"I am a 赛车 白色"*/newtoy.price; /*100*/newtoy.rating; /*3*/newtoy.getInfo(); /*Rating : 3, price:100*/
- 自身属性与原型属性
1)自身属性的优先级高于原型属性。也就是说,当我们使用对象的某个属性,它会先从对象自身查看,如果找到了,就不会在去原型中查看
2)这时如果我们仍然想得到原型中的该属性,我们可以使用 delete操作符(delete操作符,只会删除对象自身的属性,如:delete newtoy.name;)
3) 我们通过hasOwnprototype()方法来判断一个属性是来自自身属性还是原型属性
newtoy.hasOwnProperty('name'); /*true*/
- 枚举属性
var o = {x:1,y:2,z:3};console.log('toString' in o); //trueconsole.log(o.propertyIsEnumerable('toString')) //falsevar key;for (key in o){ console.log(key); //x y z}var obj = Object.create(o); //指向aobj.a = 4;console.log('x' in o) //我们通过Object.create的JavaScript内置函数,把obj指向了对象o,此时o就是obj的原型/*1)遍历对象和原型链上的属性*/var key;for (key in obj){ console.log(key); //a x y z}/*2)给for in 遍历一个条件(如果他是对象身上的属性则遍历:obj.hasOwnProperty(key))让他只遍历这个对象上的属性,而不再遍历这个对象原型链上的属性。*/var key;for (key in obj){ if (obj.hasOwnProperty(key)){ console.log(key); //a }}
2)对象及原型属性方法
isPrototypeOf()方法:这个方法告诉我们当前对象是否是一个对象的原型
/*我们先来定义一个简单的对象*/var monkey = { hair : true, feeds : 'bananas', breathes: 'air' };/*我们在创建一个叫做Hunan()的构造器函数,并将其原型属性设置为指向monkey*/function Human() { this.name = name;}Human.prototype = monkey ;/*然后我们新建一个叫做george的Human对象*/var george = new Human('George');monkey.isPrototypeOf(george); /*true*/
通过这种方法:我们将Hunam构造函数的对象的原型指向了monkey;
我还在控制台做了下面测试:也是一样的结果(设置Human原型属性的同时赋给monkey)
现在:大多数浏览器都可以在不知道原型是什么的情况下,获得对象的原型:Object.getPrototypeOf()
Object.getPrototypeOf(george).feeds; /*banana*/Object.getPrototypeOf(george) === monkey ; /*true*/
hasOwnPrototype()方法:判断一个属性是来自自身属性还是原型属性
Human.hasOwnProperty('name') /*true*/
propertyIsEnumerable()方法:判断对象的某个属性是否可枚举(默认为false)
Human.propertyIsEnumerable('name') /*false*/
有时,我们需要知道一个对象有哪些属性标签,并且指定这些属性:
Object.getOwnPropertyDescriptor():查看一个对象都有哪些属性标签:
Object.getOwnPropertyDescriptor(Human,'name')/*Object {value: "Human", writable: false, enumerable: false, configurable: true}*/;
上面四种属性标签依次为:name的值,是否可以被修改,是否可以被枚举,是否可以被删除
Object.defineProperty():我们还可以通过这种方法来管理设置这些属性
同时还可以使用Object.defineProperties()方法来指定一个对象的多个属性的值:
Object.defineProperties(person,{ name:{value:'George',enumerable:true}, feeds:{value:'banbaas',enumerable:true}, })