JavaScript中的基本数据类型
number(数值类型)
string(字符串类型)
boolean(布尔类型)
null(空类型)
undefined(未定义类型)
object
对象是什么
对象是包含相关属性和方法的集合体。
在JavaScript中,对象是拥有属性和方法的数据,属性是与对象相关的值,方法是能够在对象上执行的动作。
什么是面向对象
面向对象仅仅是一个概念或者编程思想
通过一种叫做原型的方式来实现面向对象编程
创建对象
在JavaScript中,对象分为两种:
自定义对象
内置对象
1、自定义对象
创建自定义对象的最简单的方式就是使用操作符new创建一个Object的实例,然后通过“.”为其添加属性和方法。
语法:
var 对象名称=new Object( );
例如:
<body> <script> var flower=new Object(); flower.name="长春花"; flower.genera="夹竹桃科"; flower.area="非洲、亚热带"; flower.uses="观赏或用药等"; flower.showName=function(){ alert(this.name); } flower.showName(); </script> </body>
在JavaScript中还有一种使用字面量赋值的方式在定义对象的时候为其添加属性和方法,这样创建的对象、其方法和属性可以直接使用对象引用。
例如:
<body> <script> var flower={ name:"长春花", genera:"夹竹桃科", area:"非洲、亚热带", uses:"观赏或用药等", showName:function(){ alert(this.name); } } flower.showName(); </script> </body>
常见的内置对象
String(字符串)对象
Date(日期)对象
Array(数组)对象
Boolean(逻辑)对象
Math(算数)对象
RegExp对象
构造函数和原型对象
构造函数可用来创建特定类型的对象,所谓的构造函数就是一个普通函数,但是内部使用了this变量,对构造函数使用new操作符,就能生存实例,并且this变量会绑定在实例对象上,从而定义自定义对象类型的属性和方法。
例如:
<body> <script> function Flower(name,genera,area,uses){ this.name=name; this.genera=genera; this.area=area; this.uses=uses; this.showName=showName; } function showName(){ alert(this.name); } var flower1=new Flower("长春花","夹竹桃科 长春花属","非洲、亚热带、热带以及中国大陆的华东、西南、中南等地","观赏或用药等"); var flower2=new Flower("牡丹","芍药科 芍药属","中国","观赏、食用或药用"); var flower3=new Flower("曼陀罗花","茄科 曼陀罗属","印度、中国北部","观赏或药用"); flower1.showName(); flower2.showName(); flower3.showName(); alert(flower1 instanceof Object); alert(flower1 instanceof Flower); alert(flower2 instanceof Object); alert(flower2 instanceof Flower); alert(flower3 instanceof Object); alert(flower3 instanceof Flower); alert(flower1.constructor==Flower); alert(flower2.constructor==Flower); alert(flower3.constructor==Flower); </script> </body>
注:对象的constructor属性最初是用来标识对象类型的,但是检查对象类型,还是instanceof操作符要更可靠
调用构函数的4个步骤
1、创建一个新对象
2、将构造函数的作用域赋给新对象(this就指向了这个新对象)
3、执行构造函数中的代码
4、返回新对象
原型对象
在JavaScript中创建的每个函数都有一个prototype对属性,这个属性是一个指针,指向一个对象而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
声明一个函数,则这个函数默认会有一个属性叫 prototype 。而且浏览器会自动按照一定的规则 创建一个对象,这个对象就是这个函数的原型对象,prototype属性指向这个原型对象。这个原型对象 有一个属性叫constructor 执行了这个函数
使用原型对象的好处:
可以让所有对象实例共享它所有的属性和方法,也就是说不必在构造函数中定义对象实例的信息,可以将这些信息直接添加到原型对象中。
例如:
<body> <script> function Flower(){ } Flower.prototype.name="曼陀罗花"; Flower.prototype.genera="茄科 曼陀罗属"; Flower.prototype.area="印度、中国北部"; Flower.prototype.uses="观赏或药用"; Flower.prototype.showName=function() { alert(this.name); } /*var flower1=new Flower(); flower1.showName(); var flower2=new Flower(); flower2.showName(); alert(flower1.showName==flower2.showName);*/ var flower1=new Flower(); var flower2=new Flower(); flower1.name="长春花"; alert(flower1.name); alert(flower2.name); </script> </body>
在默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个执行prototype属性所在函数的指针。
原型链
一个原型对象是另一个原型对象的实例
相关的原型对象层层递进,就构成了实例与原型的链条,就是原型链
在JavaScript中,每个构造函数都拥有一个原型对象,原型对象都包含一个执行构造函数的执行(constructor),实例都包含一个指向原型对象的内部指针(_proto_)
例如:
<body> <script> function Humans(){ this.foot=2; } Humans.prototype.getFoot=function(){ return this.foot; } function Man(){ this.head=1; } Man.prototype=new Humans(); //继承了Humans Man.prototype.getHead=function(){ return this.head; } var man1=new Man(); alert(man1.getFoot()); //返回2 alert(man1.getHead()); //返回1 alert(man1 instanceof Object); //返回true alert(man1 instanceof Humans); //返回true alert(man1 instanceof Man); //返回true </script> </body>
调用man1.getFoot( ) 经历的三个步骤
搜索实例
搜索Man.prototype
搜索Humans.prototype
从上面的代码和原型链中可以看到,子类型有时候要重写父类型中的某个方法,或者添加父类型中不存在的某个方法,但不管怎么样,给原型添加方法的代码一定要放在替换原型的语句之前。
例如:
<body> <script> function Humans(){ this.foot=2; } Humans.prototype.getFoot=function(){ return this.foot; } function Man(){ this.head=1; } //继承了Humans Man.prototype=new Humans(); //添加新方法 Man.prototype.getHead=function(){ return this.head; } //重写父类型中的方法 Man.prototype.getFoot=function(){ return false; } var man1=new Man(); alert(man1.getFoot()); //false </script> </body>
对象继承
1、借用构造函数
在子类构造函数的内部通过apply()或call()方法调用父类型的构造函数,也可以在将来新创建的对象上执行构造函数。
语法:
apply([thisOjb[,argArray]])
应用某一对象的一个方法,用另一个对象替换当前对象
接收两个参数,一个是函数运用的作用域(this),另一个参数是数组
call([thisObj[,arg1[,arg2[, [,argN]]]]])
调用一个对象的一个方法,以另一个对象替换当前对象
第一个参数是函数运用的作用域(this),第二个是传递的参数,必须一一列举出来
例如:
<body> <script> function Humans(){ this.clothing=["trousers","dress","jacket"]; } function Man(){ Humans.call(this); //继承了Humans } var man1=new Man(); man1.clothing.push("coat"); alert(man1.clothing); var man2=new Man(); alert(man2.clothing); </script> </body>
借用构造函数传递参数
例如:
<body> <script> function Humans(name){ this.name=name; } function Man(){ Humans.call(this,"mary"); //继承了Humans,同时还传递了参数 this.age=38; //实例属性 } var man1=new Man(); alert(man1.name); //输出mary alert(man1.age); //输出38 </script> </body>
2、组合继承
组合继承:有时也叫做伪经典继承
将原型链和借用构造函数的技术组合到一块,发挥二者之长的一种继承模式
使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承
例如:
<body> <script> function Humans(name){ this.name=name; this.clothing=["trousers","dress","jacket"]; } Humans.prototype.sayName=function(){ alert(this.name); }; function Man(name,age){ Humans.call(this,name); //继承属性 this.age=age; } Man.prototype=new Humans(); //继承方法 Man.prototype.sayAge=function(){ alert(this.age); }; var man1=new Man("mary",38); man1.clothing.push("coat"); alert(man1.clothing); //输出"trousers,dress,jacket,coat" man1.sayName(); //输出mary man1.sayAge(); //输出38 var man2=new Man("tom",26); alert(man2.clothing); //输出"trousers,dress,jacket" man2.sayName(); //输出tom man2.sayAge(); //输出26 </script> </body>