作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
1.什么是JavaScript?
它是Java的一个子集,但是它和Java是两种不同的语言,后者偏重于服务器端的控制,而前者则是在浏览器中做动态交互,来源于ECMA脚本语言。
2.如何运行?
其为解释性语言,在浏览器中解释运行,ASP、Ruby都是解释语言。
3.什么时候用?
扩展HTML的时候。比如创建Cookies、表单建立、建立有效果的按钮、建立弹出窗口、使用CSS的时候。
4.与其他语言相比,JS的语言特点是什么?
- 大小写敏感,HTML则不是。
- 为了适应不同的浏览器,有时要进行能力检测。
- 不强制有分号,但是建议有。
- 单引号和双引号没有特殊区别,建议使用单引号,因为XHTML规范要求所有属性值都用双引号。单引号和双引号能相互包含,除非当为了区分字符串结束,否则不需要进行转义。
- 括号可以表示表达式:(function (){})()表示定义并执行该函数,匿名。
- 直接使用函数名赋给一个变量表示将函数的引用赋值给该变量,可以类比为函数指针赋值。
- 不支持函数重载,同时定义同名函数,后边的定义覆盖前边的定义,同理,若定义与系统函数相同的函数则覆盖系统函数。函数参数个数并不要求,可以不定义,但是为了程序清晰建议定义清楚。
- 闭包:与作用域相关,指的是内部函数即使在外部函数执行完成并终止后仍然可以访问其外部函数属性。
JS是一种基于原型(prototype)的面向对象的语言,没有类的概念 ,所有的一切都派生自现有对象的一个副本。
内置对象:
- Function对象:除了作为函数直接调用外,还可以作为构造函数,必须通过new关键字来进行实例化。
- Object对象:通用的基础对象,可以使用它来创建简单的静态对象,简写为{},等价于new Object(),无法直接调用,具有固定功能。
- Array对象:数组对象,简写为[];数组有两种实现方案——顺序数组、散列数组(key,value)
- String、Boolean、Number、Math、Date、RegExp及其他内置对象。
构造方法:function myConstructor(a){}来实现,这是一个对象模板——可以理解为一个类的定义的开始。等价于var myConstructor=function(){};建议使用前者,因为前者是全局。
对象成员:
- private函数,在构造方法中直接定义function。只能被privileged函数调用。
- private成员,在构造方法中用var定义。无法被自身public方法获取、更不能被外部直接获取。从构造函数传入的参数都属于private。
- public函数可以被覆盖,使用prototype属性,在构造函数外使用Constructor.prototype .functionName= function functionName(){}来注明。
- public变量成员,使用this这个关键字(表示对象实例),其标记为public。
- privileged函数,可以使用private成员和函数,在对象外可以被调用,但是不能被覆盖。this.memberName= function functionName(){}
- privileged成员,可以在对象外使用,也可以被覆盖。
- prototype 属性 成员,只适用于对象的一个实例:Constructor.prototype .memberName = value;
- static属性成员,Constructor.memberName = value;整个对象模型就维护一个这样的成员。
- private和previleged成员占用内存大。
- function Person(n,race){
- this.constructor.population++;
- // ************************************************************************
- // PRIVATE VARIABLES AND FUNCTIONS
- // ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE
- // ***********************************************************************
- var alive=true, age=1;
- var maxAge=70+Math.round(Math.random()*15)+Math.round(Math.random()*15);
- function makeOlder(){ return alive = (++age <= maxAge) }
- var myName=n?n:"John Doe";
- var weight=1;
- // ************************************************************************
- // PRIVILEGED METHODS
- // MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS
- // MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS
- // ************************************************************************
- this.toString=this.getName=function(){ return myName }
- this.eat=function(){
- if (makeOlder()){
- this.dirtFactor++;
- return weight*=3;
- } else alert(myName+" can't eat, he's dead!");
- }
- this.exercise=function(){
- if (makeOlder()){
- this.dirtFactor++;
- return weight/=2;
- } else alert(myName+" can't exercise, he's dead!");
- }
- this.weigh=function(){ return weight }
- this.getRace=function(){ return race }
- this.getAge=function(){ return age }
- this.muchTimePasses=function(){ age+=50; this.dirtFactor=10; }
- // ************************************************************************
- // PUBLIC PROPERTIES -- ANYONE MAY READ/WRITE
- // ************************************************************************
- this.clothing="nothing/naked";
- this.dirtFactor=0;
- }
- // ************************************************************************
- // PUBLIC METHODS -- ANYONE MAY READ/WRITE
- // ************************************************************************
- Person.prototype.beCool = function(){ this.clothing="khakis and black shirt" }
- Person.prototype.shower = function(){ this.dirtFactor=2 }
- Person.prototype.showLegs = function(){ alert(this+" has "+this.legs+" legs") }
- Person.prototype.amputate = function(){ this.legs-- }
- // ************************************************************************
- // PROTOTYOPE PROERTIES -- ANYONE MAY READ/WRITE (but may be overridden)
- // ************************************************************************
- Person.prototype.legs=2;
- // ************************************************************************
- // STATIC PROPERTIES -- ANYONE MAY READ/WRITE
- // ************************************************************************
- Person.population = 0;
- // Here is the code that uses the Person class
- function RunGavinsLife(){
- var gk=new Person("Gavin","caucasian"); //New instance of the Person object created.
- var lk=new Person("Lisa","caucasian"); //New instance of the Person object created.
- alert("There are now "+Person.population+" people");
- gk.showLegs(); lk.showLegs(); //Both share the common 'Person.prototype.legs' variable when looking at 'this.legs'
- gk.race = "hispanic"; //Sets a public variable, but does not overwrite private 'race' variable.
- alert(gk+"'s real race is "+gk.getRace()); //Returns 'caucasian' from private 'race' variable set at create time.
- gk.eat(); gk.eat(); gk.eat(); //weight is 3...then 9...then 27
- alert(gk+" weighs "+gk.weigh()+" pounds and has a dirt factor of "+gk.dirtFactor);
- gk.exercise(); //weight is now 13.5
- gk.beCool(); //clothing has been update to current fashionable levels
- gk.clothing="Pimp Outfit"; //clothing is a public variable that can be updated to any funky value
- gk.shower();
- alert("Existing shower technology has gotten "+gk+" to a dirt factor of "+gk.dirtFactor);
- gk.muchTimePasses(); //50 Years Pass
- Person.prototype.shower=function(){ //Shower technology improves for everyone
- this.dirtFactor=0;
- }
- gk.beCool=function(){ //Gavin alone gets new fashion ideas
- this.clothing="tinfoil";
- };
- gk.beCool(); gk.shower();
- alert("Fashionable "+gk+" at "
- +gk.getAge()+" years old is now wearing "
- +gk.clothing+" with dirt factor "
- +gk.dirtFactor);
- gk.amputate(); //Uses the prototype property and makes a public property
- gk.showLegs(); lk.showLegs(); //Lisa still has the prototype property
- gk.muchTimePasses(); //50 Years Pass...Gavin is now over 100 years old.
- gk.eat(); //Complains about extreme age, death, and inability to eat.
- }
注意当字符串连接时toSrting方法被默认隐式调用,另外,JS中自带类的toString方法不能覆盖。
继承:通过简单的从一个对象的原型向另一个对象原型复制方法而实现的。
这是一个HTML文件 ,我们可以看到JavaScript的继承使用了原型链的方式,一环又一环的继承父类的一些属性。
- <!--
- ------ OBJECTIVES ----
- 1. Illustrate Inerhitance using JavaScript
- 2. Define a base object called Machine
- 3. Create sub object called CashRegister that inherits attributes from Machine
- -->
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>JavaScript - Inheritance Exercise</title>
- </head>
- <body>
- <p>
- <mce:script language="JavaScript" type="text/JavaScript"><!--
- // ************************************************************************
- //Define a Machine object
- // ************************************************************************
- function Machine()
- {
- //Add attributes to the Machine
- this.startingCash = 0;
- this.usedByEmployee = "Employee has not be assigned";
- }
- // ************************************************************************
- // Define a CashRegister object
- // ************************************************************************
- function CashRegister()
- {
- //Add attributes to the CashRegister
- this.startingCash = 1000;
- this.tax = .07;
- }
- // ************************************************************************
- // Use the CashRegister prototype to inherit from Machine 开始继承!
- // ************************************************************************
- CashRegister.prototype = new Machine();
- //Use the CashRegister prototype to inherit from Machine
- CashRegister.prototype.getStartingCash = function()
- {
- return this.startingCash;
- }
- // ************************************************************************
- // Use the CashRegister prototype to access Machine attributes沿原型链去读
- // ************************************************************************
- CashRegister.prototype.getUsedByEmployee = function()
- {
- return this.usedByEmployee;
- }
- // ************************************************************************
- // Define a JavaScript function to drive the test
- // ************************************************************************
- function performTest()
- {
- // ************************************************************************
- // Create an instance of myCashRegister
- // ************************************************************************
- var myCashRegister= new CashRegister();
- // ************************************************************************
- // Access the redifined attribute of CashRegister
- // ************************************************************************
- alert("The Starting Cash is: " + myCashRegister.getStartingCash() );
- // ************************************************************************
- // Access the base attribute of CashRegister
- // ************************************************************************
- alert("The Used By Employee Cash is: " + myCashRegister.getUsedByEmployee() );
- }
- // --></mce:script>
- </p>
- <p align="center"><font size="+3" face="Arial, Helvetica, sans-serif">Inheritance
- Example</font></p>
- <p align="center"> </p>
- <form name="form1" method="post" action="">
- <div align="center">
- <!-- Add button to call JavaScript function -->
- <input type="button" name="peformTest" value="Perform Test" onclick="javascript:performTest()">
- </div>
- </form>
- </body>
- </html>
对象的实质:
实质为散列数组,一个存储体,只有一个操作——成员访问操作,都是属性,没有方法。原型实质上就是一个对象被创建后,引擎默认创建一个空的prototype对象,原型中读的时候就沿着原型链向上读,写的时候向自己去写。 换句话说,在JS中,对象是一系列键值对的集合,键是一个字符串,而值则可能是一个整数、字符串、或者布尔等等,是一个函数时,我们就称其为是一个对象的方法(当然,这个值也可以是一个对象),在内存模型中用哈希表实现保证了速度。
比如:
obj = new Object;
obj.x = 1;
obj.y = 2;
在下边例子中,我们自定义了一个对象,然后用new关键词创建:
function Foo()
{
this.x = 1;
this.y = 2;
}
obj = new Foo;
内存模型如下:
下边的这个例子原型链:Object->Object2->Object3
function Object2(){}
function Object3(){}
Object2.prototype=new Object2();//继承
Object.prototype.foo=...;//这也是定义静态对象成员的一个方式。
aObj=new Object3();
aObj.foo();//实际执行了Object的foo方法——实际是一个属性
Object2.prototype.foo=...;
aObj.foo();//实际执行了Object2的foo方法——实际是一个属性
我们再举一个原型链的例子:
Object.prototype.inObj = 1;
function A()
{
this.inA = 2;
}
A.prototype.inAProto = 3;
B.prototype = new A; // Hook up A into B's prototype chain
B.prototype.constructor = B;
function B()
{
this.inB = 4;
}
B.prototype.inBProto = 5;
x = new B;
document.write(x.inObj + ', ' + x.inA + ', ' + x.inAProto + ', ' + x.inB + ', ' + x.inBProto);
X的原型链如下:
执行结果和内存模型如下:
function Foo()
{
this.x = 1;
}
Foo.prototype.AddX = function(y) // Define Method
{
this.x += y;
}
obj = new Foo;
obj.AddX(5); // Call Method
内存模型如下:
对象字面量:
这种语法创建一个对象,里面都是静态方法或者静态属性,写法更为清晰,如下,
var myObj={
propertyA:'value';
methodA:function(){}
}
相当于:
var myObj={};
myObj.propertyA='value';
myObj.methodA='value';
也可以用来设置公有成员:
function myConstructor(){}
myConstructor.prototype={
propertyA:'value',
methodA:function(){}
}
因为prototype是个对象。
call和apply函数:
可以指定的函数执行环境(也就是this的引用),有参数的用前者,当然也可以用后者,将参数作为数组放在第二个参数的位置上进行传递。