使用方法
在JavaScript中,Object对象默认定义了多个原型方法,由于继承关系所有对象都将拥有这些方法
toString()
toSting方法能够返回一个对象的字符串表示,它返回的字符串比较灵活
示例1
function F(x,y){
this.x=x,
this.y=y
}
var f=new F(1,2)
console.log(f.toString()) //[object Object]
console.log(f) //F {x: 1, y: 2}
示例2 重写toString()
function F(x,y){
this.x=x,
this.y=y
F.prototype.toString=function(){
return "x:"+this.x+",y:"+this.y
}
}
Object.prototype.toString=function(){
return this.constructor.toString()
}
var f=new F(1,2)
console.log(f.toString()) //x:1,y:2
console.log(f) //F {x: 1, y: 2}
使用valueOf()
能够返回对象的值,Object对象默认valueOf方法返回值与toSting方法返回值相同,但是部分类型对象重写了valueOf方法。对于String、Number和Boolean这些具有原始值的对象,它们的valueOf方法会返回合适的原始值
检测私有属性
根据继承关系的不同,对象属性可以分为两类:私有属性和继承属性
hasOwnProperty()方法可以检测属性的类型,私有属性返回true,继承属性返回false
遍历对象属性
var obj = {
x: 1,
y: 2,
sum: function() {
return this.x + this.y
}
}
for (var name in obj) {
if (typeof obj[name] != 'function') {
document.write(name + ':' + obj[name] + '<br />')
}
}
注:propertyIsEnumerable()方法可以判断属性是否可枚举,可以枚举返回true
检测原型对象
Function对象预定义了prototype属性,该属性指向一个原型对象。当定义构造函数时,系统会自动创建一个对象,并传递给prototype属性,这个对象被称为原型对象。原型对象可以存储构造类型的原型属性,以便让所有示例对象共享
var f = function() {} //定义函数
f.prototype = { //函数的原型对象
a: 1,
b: function() {
return 2
}
}
console.log(f.prototype.a, f.prototype.b()) //读取原型对象属性a和属性b
var o = new f() //实例对象
console.log(o.a, o.b()) //访问原型对象的属性
使用原型
构造函数拥有原型,实例对象通过prototype关键字可以访问原型,可以通过function.prototype方式定义原型,从而影响所有实例对象
比较原型属性和本地属性
原型属性: 原型属性将会影响所有实例对象,修改任何原型属性值,则构造函数的所有实例都会看到这种变化,避免了本地属性修改的麻烦
function f() {
f.prototype.a = 1 //原型属性
}
var f1 = new f()
var f2 = new f()
console.log(f1.a, f2.a)
f.prototype.a = 2
console.log(f1.a, f2.a)
原型属性值会影响所有实例对象的属性值,对于原型方法也是如此
本地属性
function f() {
this.a = 1 //本地属性
}
var f1 = new f()
如果给构造函数定义了与原型属性同名的本地属性,则本地属性会覆盖原型属性值
本地属性可以在实例对象中被修改,但是不同实例对象直接不会相互干扰
原型继承
在原型继承中,类和实例概念被淡化,一切都从对象的角度来考虑。原型继承不再需要使用类来定义对象的结构,直接定义对象,并被其它对象引用,这样就形成了一种继承关系,其中引用对象被称为原型对象
示例
function A(x) { //A类
this.x = x //A的本地属性x1
this.get1 = function() { //A的本地方法get1
return this.x
}
}
function B(x) {
this.x2 = x
this.get2 = function() {
return this.x2
}
}
B.prototype = new A(1) //原型对象继承A的实例
function C(x) {
this.x3 = x
this.get3 = function() {
return this.x3
}
}
C.prototype = new B(2) //原型对象继承B的实例
prototype的最大特点就是能够运行对象实例共享原型对象成员,如果把某个对象作为一个类型的原型,那么说这个类型的实例以这个对象为原型
缺点:
1、每个类型只有一个原型,所以它不直接支持多重继承
2、使用不够灵活。用户需要在原型声明阶段实例化父类对象,并把它作为当前类型的原型,这限制了父类实例化的灵活性,很多时候无法确定父类对象实例化的时机和场所
扩展原型方法
JavaScript允许为基本数据类型定义方法。通过Object.prototype添加原型方法,可以使得该方法对所有对象可用。这样的方法对函数
、数组、字符串、数字、正则表达式和布尔值都适用
示例 通过给Function.prototype增加方法,是该方法对所有函数可用
Function.prototype.method = function(name, func) {
this.prototype[name] = func
return this
}
示例 通过为Number.prototype添加一个integer方法来提取数字中的整数部分
Function.prototype.method = function(name, func) {
this.prototype[name] = func
return this
}
Number.method('integer', function() {
return Math[this < 0 ? 'ceil' : 'floor'](this)
})
document.write((-10 / 3).integer())