Javascript原型表述
Javascript有两种开发模式: 1.面向过程, 2.面向对象。不论是面向过程还是面向过程,他们都是一种思维方式。
面向过程着重强调的是,在处理问题过程中,侧重于如何逐步实现达到效果;
然而在面向对象中,需要树立两个重要的概念:类的概念、对象的概念。类的概念即是一种抽象的概念,对象则是实际的案例。通过类可以创建任意多个具有相同属性和方法的对象。
面向对象语言的特性:
1.封装;
2.继承;
3.多态。
javascript中获得对象的方法
方法有三种,分别是:
1.通过 new Object 得到;
2.通过创建Json得到;
3.通过构造函数得到。
在以上三种方法中,第一种使用new Object的获取,因为并没有引入类的概念,所以如果定义有多个对象的时候,需要进行重复的定义;同样的,使用Json获取对象也存在不能重用对象的问题;那么就使用构造函数的方法既能够解决对象重用的问题,也加入了“类”的概念,能够使用instanceof进行类的判断(不适用typeOf(),因为其只能检测出Object())。
原型
原型即是javascript中一个特殊的对象,当函数对象创建的时候,随之产生一个原型对象。若是通过该函数的构造函数创建了一个具体的对象之后,在这个具体的函数对象中,会出现一个属性,该属性指向原型。
(针对于产生的该属性类似于指针,指向原型。但是在js中并没有指针这个概念,所以在此引用“指针”只是为了方便理解)
原型的内存模式有以下几个步骤:
Step1:
定义function Ball(){}之后,内存中创建了一个Ball对象,随之产生一个prototype属性,指向了Ball对象的原型对象,而原型对象中存在了一个constractor的属性,指向Ball对象。
Step2:
要在Ball.prototype.name = football,进行赋值之后,这些属性和方法都赋在了Ball对象的原型对象上。
Step3:
根据Ball构造函数创建一个对象b1之后,该对象中存在了一个prop的属性,也指向了Ball对象的原型对象,当我们调用该对象的属性和方法的时候,首先在自己的内容中寻找,若是找不到,就去Ball对象的原型对象中寻找。
Step4:
当创建了一个新的对象b2时,那么在b2中同样存在了一个prop的属性指向Ball对象的原型对象。如果b2的属性和方法重新赋值的话,当我们调用时,会调用到我们赋的值,同样的,首先在自己的内容中寻找,若是找不到,就去Ball对象的原型对象中寻找。(在此过程中,原型中的属性和方法不会被覆盖)
常见的原型检测方式
可以通过如下的方式检测b1是不是指向Ball的原型对象
alert(Ball.prototype.isPrototypeOf(b1))
//检测b1的构造器是否指向Ball对象
alert(b1.constructor == Ball)
//检测某个属性是不是自己内存中的
alert(b1.hasOwnProperty("name"));
alert(b2.hasOwnProperty("name"))
可以使用delete语句删除对象中自己的属性,那么就会找到原型中的值
delete b2.name;
b2.say();
alert(b2.hasOwnProperty("name"));
检测在某个对象自己或者对应的原型中是否存在某个属性。
alert("name" in b1);//true
delete b2.name;//虽然删除了自己的name属性,但是原型中有
alert("name" in b2);//true
//原型和自己中都没有size属性
alert("size" in b1);//false
原型重写
为了解决大量的 [对象.prototype.属性名 ] 的书写问题,可以使用json的方法进行:
function Ball() {
}
Ball.prototype = {
name : "football",
color : "black&white",
say : function() {
alert("my name is: "+this.name+",my color is"+this.color);
}
}
var b1 = new Ball();
b1.say()
var b2 = new Ball();
b2.name = "张三";
b2.color = blue;
b2.say();
function Ball() {
}
Ball.prototype = {
constructor:Ball, //手动指向原型对象
name : "basketball",
age : brown,
say : function() {
alert("my name is : "+this.name+",my color is"+this.age);
}
}
var b1 = new Ball();
b1.say()
var b2 = new Ball();
b2.name = "baseball";
1.封装
因为原型存在,我们实现了对象的封装,但是这种封装也同样可能存在问题的。
1、 我们无法像使用构造函数的那样将属性传递用于设置值
2、 当属性中有引用类型, 可能存在变量值的重复
为了解决原型所带来的问题,需要通过组合构造函数和原型来实现对象的创建:属性在构造函数中定义,方法在原型中定义。这种有效集合了两者的优点,是目前最为常用的一种方式。