首页 > 代码库 > 面向对象(二)
面向对象(二)
学了这么久还是对面向对象有点模糊,所以今天就再写一点关于面向对象的
function Box(){} var box=new Box(); alert(box.prototype) //undifined 使用对象实例无法访问到prototype alert(box.__proto__);//object object 使用对象实例访问prototype的指针 alert(Box.prototype);//object object 使用构造函数名(对象名)访问prototype
说明对象的实例是无法直接通过prototype属性访问该构造方法的原型的,但是对象实例可以通过访问prototype的指针的方式来访问,同时构造函数(即对象名) 访问prototype。
二、为了让属性和方法更好的体现封装效果,并减少不必要的输入,原型对象也可以用字面量的方式来创建,代码如下
function Box(){} Box.prototype={ ① name:‘Lee‘, age:‘27‘, run:function(){ return this.name+this.age; } }
注意:①处的{}其实就是Object,new Object就相当于{}
使用构造函数创造源性对象与字面量创造原型对象在使用上基本相同,但是有一些区别,那就是 用字面量的方式 使用constructor属性不会指向实例(Box),而是会指向Object,构造函数的方式则不会出现这个问题,会指向(Box),具体看下面代码
var box=new Box(); alert(box.constructor)//function Object{}
ps:字面量的方式为什么会是constructor属性指向Object呢?那是因为,Box.prototype={}这种方式其实是创建了一个新对象,而每创建一个对象,就会同时创建他的prototype对象,这个对象也会自动获取constructor属性,所以新对象的constructor重写了Box原来的constructor,所以会指向新对象,那个新对象没有指定构造函数,所以就默认为Object了
当然也有办法让他的constructor重新指向Box,看如下代码
function Box(){} Box.prototype={ constructor:Box, //强制指向Box name:‘Lee‘, age:‘27‘, run:function(){ return this.name+this.age; } } var box=new Box(); alert(box.constructor)//function Box{}
用constructor:Box,就会让他重新 指向 Box实例
三、原型的声明是有先后的,所以重写的原型,会切断之前的原型
function Box(){} Box.prototype={ constructor:Box, //强制指向 Box name:‘Lee‘, age:‘27‘, run:function(){ return this.name+this.age; } } Box.prototype={ //重写了原型对象,这里不会保留之前的原型的任何信息 age:‘100‘ } var box=new Box(); alert(box.name);//undifined
这个很好理解,第二次Box.prototype把第一次的给重写了,表面上是改了 age的值,其实是 把整个原型都重写了,所以上面的原型彻底与构造函数实例切断,box.name在第二次根本不存在,因此,undifined也是自然而然的事情了
// //查询sort是否是Array源性对象里的方法 // alert(Array.prototype.sort); // alert(String.prototype.substring); // 给String添加方法 String.prototype.addString = function() { //尽管给原生的内置引用类型添加方法特别方便,但我们不推荐这种方法 //因为他可能导致命名冲突,不利于代码维护 return this + "被添加了、、、"; } alert("xixida".addString()); //xixida被添加了、、、
面向对象(二)